diff --git a/.gn b/.gn index 243474c50..1f94854 100644 --- a/.gn +++ b/.gn
@@ -24,7 +24,9 @@ "//cc/*", #"//chrome/*", # Epic number of errors. + "//chrome/common/*", "//chrome/installer/*", + "//chrome/third_party/mozilla_security_manager/*", "//chromecast/*", # TODO(brettw): Fix http://crbug.com/460828 and uncomment the following
diff --git a/DEPS b/DEPS index c778604b..d0491d1e 100644 --- a/DEPS +++ b/DEPS
@@ -39,15 +39,15 @@ # 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': 'e9759286e8eb3a0ce00923bf9462818bc67cd9f8', + 'skia_revision': '338047e21fa321a708cd59d6f3dfdab753cf6404', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '8ee0ef529bc0f5b171bfb92fa76051ca9a6f63b5', + 'v8_revision': '97a062a564b09b498633305a4500a6c5a5016f93', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. - 'swarming_revision': 'e4c0e242eeec361886ed2b89591a505ebe24db43', + 'swarming_revision': '3db878084b52a5e4eac0a32095e490e1b6ef9526', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. @@ -67,7 +67,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling BoringSSL # and whatever else without interference from each other. - 'boringssl_revision': '0dd93002ddf5adce17db88f1212ca2e14eba6e9c', + 'boringssl_revision': '63fa118f3a3d065adb6ca17227bb9e407ffadccb', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling nss # and whatever else without interference from each other.
diff --git a/android_webview/browser/hardware_renderer.cc b/android_webview/browser/hardware_renderer.cc index ff14f10..b13f0ef 100644 --- a/android_webview/browser/hardware_renderer.cc +++ b/android_webview/browser/hardware_renderer.cc
@@ -102,10 +102,9 @@ // during "kModeSync" stage (which does not allow GL) might result in extra // kModeProcess. Instead, submit the frame in "kModeDraw" stage to avoid // unnecessary kModeProcess. - scoped_ptr<ChildFrame> child_frame = child_frame_.Pass(); - if (child_frame.get()) { + if (child_frame_.get() && child_frame_->frame.get()) { scoped_ptr<cc::CompositorFrame> child_compositor_frame = - child_frame->frame.Pass(); + child_frame_->frame.Pass(); // On Android we put our browser layers in physical pixels and set our // browser CC device_scale_factor to 1, so suppress the transform between @@ -139,7 +138,7 @@ // compositor might not have the tiles rasterized as the animation goes on. ParentCompositorDrawConstraints draw_constraints( draw_info->is_layer, transform, viewport.IsEmpty()); - if (!child_frame.get() || draw_constraints.NeedUpdate(*child_frame)) { + if (!child_frame_.get() || draw_constraints.NeedUpdate(*child_frame_)) { shared_renderer_state_->PostExternalDrawConstraintsToChildCompositorOnRT( draw_constraints); }
diff --git a/android_webview/browser/hardware_renderer.h b/android_webview/browser/hardware_renderer.h index fe7aaef..49a51ba4 100644 --- a/android_webview/browser/hardware_renderer.h +++ b/android_webview/browser/hardware_renderer.h
@@ -61,6 +61,9 @@ // Infromation from UI on last commit. gfx::Vector2d scroll_offset_; + // This holds the last ChildFrame received. Contains the frame info of the + // last frame. The |frame| member may be null if it's already submitted to + // SurfaceFactory. scoped_ptr<ChildFrame> child_frame_; scoped_refptr<AwGLSurface> gl_surface_;
diff --git a/ash/accelerators/accelerator_table.cc b/ash/accelerators/accelerator_table.cc index 6f6d4b50..35888ed 100644 --- a/ash/accelerators/accelerator_table.cc +++ b/ash/accelerators/accelerator_table.cc
@@ -264,7 +264,7 @@ {true, ui::VKEY_W, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, DEBUG_PRINT_WINDOW_HIERARCHY}, - {true, ui::VKEY_S, + {true, ui::VKEY_D, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, DEBUG_TOGGLE_DEVICE_SCALE_FACTOR}, {true, ui::VKEY_B,
diff --git a/ash/sticky_keys/sticky_keys_overlay.cc b/ash/sticky_keys/sticky_keys_overlay.cc index 3826f735..6c376cf 100644 --- a/ash/sticky_keys/sticky_keys_overlay.cc +++ b/ash/sticky_keys/sticky_keys_overlay.cc
@@ -231,7 +231,16 @@ overlay_widget_->GetNativeView()->SetName("StickyKeysOverlay"); } -StickyKeysOverlay::~StickyKeysOverlay() {} +StickyKeysOverlay::~StickyKeysOverlay() { + // Remove ourself from the animator to avoid being re-entrantly called in + // |overlay_widget_|'s destructor. + ui::Layer* layer = overlay_widget_->GetLayer(); + if (layer) { + ui::LayerAnimator* animator = layer->GetAnimator(); + if (animator) + animator->RemoveObserver(this); + } +} void StickyKeysOverlay::Show(bool visible) { if (is_visible_ == visible)
diff --git a/base/profiler/win32_stack_frame_unwinder.cc b/base/profiler/win32_stack_frame_unwinder.cc index ea589bbc..2f09e8e8 100644 --- a/base/profiler/win32_stack_frame_unwinder.cc +++ b/base/profiler/win32_stack_frame_unwinder.cc
@@ -205,7 +205,13 @@ } else { // We're not at the end of the stack. This frame is untrustworthy and we // can't safely unwind from here. - if (unwind_info_present_for_all_frames_) { + if (!image_base) { + // A null image_base means that the the last unwind produced an invalid + // instruction pointer. This has been observed where unwind information + // was present for a function but was inconsistent with the actual + // function code, in particular in BoringSSL. See + // https://crbug.com/542919. + } else if (unwind_info_present_for_all_frames_) { // Unwind information was present for all previous frames, so we can // be confident this is case 2. Record the module to be blacklisted. LeafUnwindBlacklist::GetInstance()->BlacklistModule(
diff --git a/blimp/common/proto/BUILD.gn b/blimp/common/proto/BUILD.gn index db60779..ecaa29c7 100644 --- a/blimp/common/proto/BUILD.gn +++ b/blimp/common/proto/BUILD.gn
@@ -14,10 +14,9 @@ proto_library("proto_lib") { sources = [ "blimp_message.proto", - "client_control.proto", "common.proto", "compositor.proto", + "control.proto", "input.proto", - "server_control.proto", ] }
diff --git a/blimp/common/proto/blimp_message.proto b/blimp/common/proto/blimp_message.proto index 9472f9ef..553119d 100644 --- a/blimp/common/proto/blimp_message.proto +++ b/blimp/common/proto/blimp_message.proto
@@ -24,10 +24,9 @@ option optimize_for = LITE_RUNTIME; -import "client_control.proto"; +import "control.proto"; import "compositor.proto"; import "input.proto"; -import "server_control.proto"; package blimp; @@ -35,8 +34,7 @@ enum Type { COMPOSITOR = 0; INPUT = 1; - CLIENT_CONTROL = 2; - SERVER_CONTROL = 3; + CONTROL = 2; } // Identifies the feature type of this message. // The feature-specific contents are contained in optional fields of the same @@ -59,7 +57,6 @@ // TODO(kmarshall): use a 'oneof' union when it's supported in Chromium. optional CompositorMessage compositor = 1000; optional InputMessage input = 1001; - optional ClientControlMessage client_control = 1002; - optional ServerControlMessage server_control = 1003; + optional ControlMessage control = 1002; }
diff --git a/blimp/common/proto/client_control.proto b/blimp/common/proto/client_control.proto deleted file mode 100644 index 6d9f605f..0000000 --- a/blimp/common/proto/client_control.proto +++ /dev/null
@@ -1,29 +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. -// -// Message definitions for client-originating browser control messages. -// -// Current definitions are just placeholders and are NOT final. -// Feel free to modify this interface as necessary during feature work. - -syntax = "proto2"; - -option optimize_for = LITE_RUNTIME; - -message NavigateArgs { - optional string url = 1; -} - -message ClientControlMessage { - enum Type { - NAVIGATE = 1; - STOP = 2; - RELOAD = 3; - BACK = 4; - FORWARD = 5; - } - optional Type type = 1; - - optional NavigateArgs navigate = 1000; -}
diff --git a/blimp/common/proto/control.proto b/blimp/common/proto/control.proto new file mode 100644 index 0000000..fdc1c89 --- /dev/null +++ b/blimp/common/proto/control.proto
@@ -0,0 +1,28 @@ +// 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. +// +// Message definitions for browser control messages. + +syntax = "proto2"; + +option optimize_for = LITE_RUNTIME; + +message LoadUrlMessage { + optional string url = 1; +} + +message ControlMessage { + enum Type { + // Client <=> Server types. + CREATE_TAB = 1; + CLOSE_TAB = 2; + LOAD_URL = 3; + + // Server => Client types. + // Client => Server types. + } + optional Type type = 1; + + optional LoadUrlMessage load_url = 1000; +}
diff --git a/blimp/common/proto/server_control.proto b/blimp/common/proto/server_control.proto deleted file mode 100644 index f1cf976..0000000 --- a/blimp/common/proto/server_control.proto +++ /dev/null
@@ -1,43 +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. -// -// Message definitions for server-originating browser control messages. -// -// Current definitions are just placeholders and are NOT final. -// Feel free to modify this interface as necessary during feature work. - -syntax = "proto2"; - -option optimize_for = LITE_RUNTIME; - -message StatusArgs { - optional string url = 1; - optional int32 loading_progress = 2; - // Add error code, error message, status strings, etc. -} - -message ResetSessionArgs { -} - -message ErrorArgs { - enum ErrorCode { - UNKNOWN = 1; - UNRESPONSIVE = 2; - SERVER_ERROR = 3; - } - - optional ErrorCode error_code = 1; - optional int32 server_error_code = 2; -} - -message ServerControlMessage { - enum Type { - ERROR = 1; - STATUS = 2; - } - optional Type type = 1; - - optional ErrorArgs error = 1000; - optional StatusArgs status = 1001; -}
diff --git a/blimp/engine/browser/BUILD.gn b/blimp/engine/browser/BUILD.gn index dc7ac4ae..43857f2c 100644 --- a/blimp/engine/browser/BUILD.gn +++ b/blimp/engine/browser/BUILD.gn
@@ -10,18 +10,20 @@ "blimp_browser_main_parts.h", "blimp_content_browser_client.cc", "blimp_content_browser_client.h", + "blimp_engine_session.cc", + "blimp_engine_session.h", "blimp_network_delegate.cc", "blimp_network_delegate.h", "blimp_permission_manager.cc", "blimp_permission_manager.h", "blimp_url_request_context_getter.cc", "blimp_url_request_context_getter.h", - "blimp_window.cc", - "blimp_window.h", ] deps = [ "//base", + "//blimp/common/proto", + "//blimp/net:blimp_net", "//blimp/engine/ui", "//content", "//content/public/browser",
diff --git a/blimp/engine/browser/blimp_browser_main_parts.cc b/blimp/engine/browser/blimp_browser_main_parts.cc index a1c0474..aaba2d3 100644 --- a/blimp/engine/browser/blimp_browser_main_parts.cc +++ b/blimp/engine/browser/blimp_browser_main_parts.cc
@@ -4,36 +4,17 @@ #include "blimp/engine/browser/blimp_browser_main_parts.h" -#include "base/command_line.h" -#include "blimp/engine/browser/blimp_window.h" -#include "blimp/engine/ui/blimp_screen.h" +#include "blimp/engine/browser/blimp_browser_context.h" +#include "blimp/engine/browser/blimp_engine_session.h" +#include "blimp/net/blimp_client_session.h" #include "content/public/browser/browser_thread.h" +#include "content/public/common/main_function_params.h" #include "net/base/net_module.h" #include "net/log/net_log.h" -#include "url/gurl.h" namespace blimp { namespace engine { -namespace { - -const char kDefaultURL[] = "https://www.google.com/"; - -GURL GetStartupURL() { - base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); - const base::CommandLine::StringVector& args = command_line->GetArgs(); - if (args.empty()) - return GURL(kDefaultURL); - - GURL url(args[0]); - if (url.is_valid() && url.has_scheme()) - return url; - - return GURL(kDefaultURL); -} - -} // namespace - BlimpBrowserMainParts::BlimpBrowserMainParts( const content::MainFunctionParams& parameters) {} @@ -41,20 +22,21 @@ void BlimpBrowserMainParts::PreMainMessageLoopRun() { net_log_.reset(new net::NetLog()); - browser_context_.reset(new BlimpBrowserContext(false, net_log_.get())); - BlimpWindow::Create(browser_context_.get(), GetStartupURL(), nullptr, - gfx::Size()); -} - -int BlimpBrowserMainParts::PreCreateThreads() { - screen_.reset(new BlimpScreen); - DCHECK(!gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_NATIVE)); - gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, screen_.get()); - return 0; + scoped_ptr<BlimpBrowserContext> browser_context( + new BlimpBrowserContext(false, net_log_.get())); + engine_session_.reset(new BlimpEngineSession(browser_context.Pass())); + engine_session_->Initialize(); + // TODO(haibinlu): remove this after a real client session can be attached. + scoped_ptr<BlimpClientSession> startupSession(new BlimpClientSession); + engine_session_->AttachClientSession(startupSession.Pass()); } void BlimpBrowserMainParts::PostMainMessageLoopRun() { - browser_context_.reset(); + engine_session_.reset(); +} + +BlimpBrowserContext* BlimpBrowserMainParts::GetBrowserContext() { + return engine_session_->browser_context(); } } // namespace engine
diff --git a/blimp/engine/browser/blimp_browser_main_parts.h b/blimp/engine/browser/blimp_browser_main_parts.h index 5c2e991a..77fd8b7 100644 --- a/blimp/engine/browser/blimp_browser_main_parts.h +++ b/blimp/engine/browser/blimp_browser_main_parts.h
@@ -7,17 +7,21 @@ #include "base/macros.h" #include "base/memory/scoped_ptr.h" -#include "blimp/engine/browser/blimp_browser_context.h" #include "content/public/browser/browser_main_parts.h" namespace net { class NetLog; } +namespace content { +struct MainFunctionParams; +} + namespace blimp { namespace engine { -class BlimpScreen; +class BlimpBrowserContext; +class BlimpEngineSession; class BlimpBrowserMainParts : public content::BrowserMainParts { public: @@ -27,14 +31,12 @@ // content::BrowserMainParts implementation. void PreMainMessageLoopRun() override; void PostMainMessageLoopRun() override; - int PreCreateThreads() override; - BlimpBrowserContext* browser_context() { return browser_context_.get(); } + BlimpBrowserContext* GetBrowserContext(); private: scoped_ptr<net::NetLog> net_log_; - scoped_ptr<BlimpBrowserContext> browser_context_; - scoped_ptr<BlimpScreen> screen_; + scoped_ptr<BlimpEngineSession> engine_session_; DISALLOW_COPY_AND_ASSIGN(BlimpBrowserMainParts); };
diff --git a/blimp/engine/browser/blimp_content_browser_client.cc b/blimp/engine/browser/blimp_content_browser_client.cc index 1023fbb..6163507b 100644 --- a/blimp/engine/browser/blimp_content_browser_client.cc +++ b/blimp/engine/browser/blimp_content_browser_client.cc
@@ -31,8 +31,8 @@ .get(); } -BlimpBrowserContext* BlimpContentBrowserClient::browser_context() { - return blimp_browser_main_parts_->browser_context(); +BlimpBrowserContext* BlimpContentBrowserClient::GetBrowserContext() { + return blimp_browser_main_parts_->GetBrowserContext(); } } // namespace engine
diff --git a/blimp/engine/browser/blimp_content_browser_client.h b/blimp/engine/browser/blimp_content_browser_client.h index aa566cdc..aee1c8c 100644 --- a/blimp/engine/browser/blimp_content_browser_client.h +++ b/blimp/engine/browser/blimp_content_browser_client.h
@@ -27,7 +27,7 @@ content::ProtocolHandlerMap* protocol_handlers, content::URLRequestInterceptorScopedVector request_interceptors) override; - BlimpBrowserContext* browser_context(); + BlimpBrowserContext* GetBrowserContext(); private: // Owned by BrowserMainLoop
diff --git a/blimp/engine/browser/blimp_engine_session.cc b/blimp/engine/browser/blimp_engine_session.cc new file mode 100644 index 0000000..d75bddc67 --- /dev/null +++ b/blimp/engine/browser/blimp_engine_session.cc
@@ -0,0 +1,166 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "blimp/engine/browser/blimp_engine_session.h" + +#include "blimp/common/proto/blimp_message.pb.h" +#include "blimp/common/proto/control.pb.h" +#include "blimp/engine/browser/blimp_browser_context.h" +#include "blimp/engine/ui/blimp_screen.h" +#include "blimp/net/blimp_client_session.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/navigation_controller.h" +#include "content/public/browser/navigation_entry.h" +#include "content/public/browser/render_view_host.h" +#include "content/public/browser/render_widget_host.h" +#include "content/public/browser/web_contents.h" + +namespace blimp { +namespace engine { + +BlimpEngineSession::BlimpEngineSession( + scoped_ptr<BlimpBrowserContext> browser_context) + : browser_context_(browser_context.Pass()), screen_(new BlimpScreen) {} + +BlimpEngineSession::~BlimpEngineSession() {} + +void BlimpEngineSession::Initialize() { + DCHECK(!gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_NATIVE)); + gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, screen_.get()); +} + +void BlimpEngineSession::AttachClientSession( + scoped_ptr<BlimpClientSession> client_session) { + // TODO(haibinlu): auto detaches existing client session. + if (!client_session) { + NOTIMPLEMENTED(); + return; + } + + client_session_ = client_session.Pass(); + + // TODO(haibinlu): remove this once we can use client session to send in + // a navigation message. + BlimpMessage message; + message.set_type(BlimpMessage::CONTROL); + message.mutable_control()->set_type(ControlMessage::CREATE_TAB); + OnBlimpMessage(message); + message.mutable_control()->set_type(ControlMessage::LOAD_URL); + message.mutable_control()->mutable_load_url()->set_url( + "https://www.google.com/"); + OnBlimpMessage(message); +} + +void BlimpEngineSession::CreateWebContents(const int target_tab_id) { + if (web_contents_) { + // only one web_contents is supported for blimp 0.5 + NOTIMPLEMENTED(); + return; + } + + content::WebContents::CreateParams create_params(browser_context_.get(), + nullptr); + scoped_ptr<content::WebContents> new_contents = + make_scoped_ptr(content::WebContents::Create(create_params)); + PlatformSetContents(new_contents.Pass()); +} + +void BlimpEngineSession::LoadUrl(const int target_tab_id, const GURL& url) { + if (url.is_empty() || !web_contents_) + return; + + content::NavigationController::LoadURLParams params(url); + params.transition_type = ui::PageTransitionFromInt( + ui::PAGE_TRANSITION_TYPED | ui::PAGE_TRANSITION_FROM_ADDRESS_BAR); + web_contents_->GetController().LoadURLWithParams(params); + web_contents_->Focus(); +} + +net::Error BlimpEngineSession::OnBlimpMessage(const BlimpMessage& message) { + DCHECK(message.type() == BlimpMessage::CONTROL); + + switch (message.control().type()) { + case ControlMessage::CREATE_TAB: + CreateWebContents(message.target_tab_id()); + break; + case ControlMessage::LOAD_URL: + LoadUrl(message.target_tab_id(), + GURL(message.control().load_url().url())); + break; + default: + NOTIMPLEMENTED(); + } + + return net::OK; +} + +void BlimpEngineSession::AddNewContents(content::WebContents* source, + content::WebContents* new_contents, + WindowOpenDisposition disposition, + const gfx::Rect& initial_rect, + bool user_gesture, + bool* was_blocked) { + NOTIMPLEMENTED(); +} + +content::WebContents* BlimpEngineSession::OpenURLFromTab( + content::WebContents* source, + const content::OpenURLParams& params) { + // CURRENT_TAB is the only one we implement for now. + if (params.disposition != CURRENT_TAB) { + // TODO(haibinlu): handle other disposition properly. + NOTIMPLEMENTED(); + return nullptr; + } + // TOOD(haibinlu): add helper method to get LoadURLParams from OpenURLParams. + content::NavigationController::LoadURLParams load_url_params(params.url); + load_url_params.source_site_instance = params.source_site_instance; + load_url_params.referrer = params.referrer; + load_url_params.frame_tree_node_id = params.frame_tree_node_id; + load_url_params.transition_type = params.transition; + load_url_params.extra_headers = params.extra_headers; + load_url_params.should_replace_current_entry = + params.should_replace_current_entry; + + if (params.transferred_global_request_id != content::GlobalRequestID()) { + // The navigation as being transferred from one RVH to another. + // Copies the request ID of the old request. + load_url_params.is_renderer_initiated = params.is_renderer_initiated; + load_url_params.transferred_global_request_id = + params.transferred_global_request_id; + } else if (params.is_renderer_initiated) { + load_url_params.is_renderer_initiated = true; + } + + source->GetController().LoadURLWithParams(load_url_params); + return source; +} + +void BlimpEngineSession::RequestToLockMouse(content::WebContents* web_contents, + bool user_gesture, + bool last_unlocked_by_target) { + web_contents->GotResponseToLockMouseRequest(true); +} + +void BlimpEngineSession::CloseContents(content::WebContents* source) { + if (source == web_contents_) + web_contents_.reset(); +} + +void BlimpEngineSession::ActivateContents(content::WebContents* contents) { + contents->GetRenderViewHost()->GetWidget()->Focus(); +} + +void BlimpEngineSession::DeactivateContents(content::WebContents* contents) { + contents->GetRenderViewHost()->GetWidget()->Blur(); +} + +void BlimpEngineSession::PlatformSetContents( + scoped_ptr<content::WebContents> new_contents) { + new_contents->SetDelegate(this); + web_contents_ = new_contents.Pass(); +} + +} // namespace engine +} // namespace blimp
diff --git a/blimp/engine/browser/blimp_engine_session.h b/blimp/engine/browser/blimp_engine_session.h new file mode 100644 index 0000000..c161867 --- /dev/null +++ b/blimp/engine/browser/blimp_engine_session.h
@@ -0,0 +1,85 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BLIMP_ENGINE_BROWSER_BLIMP_ENGINE_SESSION_H_ +#define BLIMP_ENGINE_BROWSER_BLIMP_ENGINE_SESSION_H_ + +#include "base/macros.h" +#include "base/memory/scoped_ptr.h" +#include "blimp/net/blimp_message_receiver.h" +#include "content/public/browser/web_contents_delegate.h" +#include "ui/gfx/geometry/size.h" + +namespace content { +class BrowserContext; +class WebContents; +} + +namespace blimp { + +class BlimpClientSession; +class BlimpMessage; + +namespace engine { + +class BlimpBrowserContext; +class BlimpScreen; + +class BlimpEngineSession : public BlimpMessageReceiver, + public content::WebContentsDelegate { + public: + explicit BlimpEngineSession(scoped_ptr<BlimpBrowserContext> browser_context); + ~BlimpEngineSession() override; + + void Initialize(); + + BlimpBrowserContext* browser_context() { return browser_context_.get(); } + + void AttachClientSession(scoped_ptr<BlimpClientSession> client_session); + + private: + // Creates a new WebContents, which will be indexed by |target_tab_id|. + void CreateWebContents(const int target_tab_id); + + // Navigates the target tab to the |url|. + void LoadUrl(const int target_tab_id, const GURL& url); + + // BlimpMessageReceiver implementation. + net::Error OnBlimpMessage(const BlimpMessage& message) override; + + // content::WebContentsDelegate implementation. + content::WebContents* OpenURLFromTab( + content::WebContents* source, + const content::OpenURLParams& params) override; + void AddNewContents(content::WebContents* source, + content::WebContents* new_contents, + WindowOpenDisposition disposition, + const gfx::Rect& initial_rect, + bool user_gesture, + bool* was_blocked) override; + void RequestToLockMouse(content::WebContents* web_contents, + bool user_gesture, + bool last_unlocked_by_target) override; + void CloseContents(content::WebContents* source) override; + void ActivateContents(content::WebContents* contents) override; + void DeactivateContents(content::WebContents* contents) override; + + // Sets up and owns |new_contents|. + void PlatformSetContents(scoped_ptr<content::WebContents> new_contents); + + scoped_ptr<BlimpBrowserContext> browser_context_; + scoped_ptr<BlimpScreen> screen_; + + // Only one web_contents is supported for blimp 0.5 + scoped_ptr<content::WebContents> web_contents_; + + // Currently attached client session. + scoped_ptr<BlimpClientSession> client_session_; + DISALLOW_COPY_AND_ASSIGN(BlimpEngineSession); +}; + +} // namespace engine +} // namespace blimp + +#endif // BLIMP_ENGINE_BROWSER_BLIMP_ENGINE_SESSION_H_
diff --git a/blimp/engine/browser/blimp_url_request_context_getter.cc b/blimp/engine/browser/blimp_url_request_context_getter.cc index e49c5f2..f2bc1dec 100644 --- a/blimp/engine/browser/blimp_url_request_context_getter.cc +++ b/blimp/engine/browser/blimp_url_request_context_getter.cc
@@ -180,10 +180,10 @@ network_session_params.host_resolver = url_request_context_->host_resolver(); - storage_->set_http_transaction_factory( - make_scoped_ptr( - new net::HttpCache(network_session_params, main_backend)) - .Pass()); + storage_->set_http_network_session( + make_scoped_ptr(new net::HttpNetworkSession(network_session_params))); + storage_->set_http_transaction_factory(make_scoped_ptr(new net::HttpCache( + storage_->http_network_session(), main_backend, true))); scoped_ptr<net::URLRequestJobFactoryImpl> job_factory( new net::URLRequestJobFactoryImpl());
diff --git a/blimp/engine/browser/blimp_window.cc b/blimp/engine/browser/blimp_window.cc deleted file mode 100644 index bc79448..0000000 --- a/blimp/engine/browser/blimp_window.cc +++ /dev/null
@@ -1,140 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "blimp/engine/browser/blimp_window.h" - -#include "base/strings/string_util.h" -#include "blimp/engine/browser/blimp_browser_main_parts.h" -#include "blimp/engine/browser/blimp_content_browser_client.h" -#include "content/public/browser/navigation_controller.h" -#include "content/public/browser/navigation_entry.h" -#include "content/public/browser/render_view_host.h" -#include "content/public/browser/render_widget_host_view.h" -#include "content/public/browser/web_contents.h" - -namespace blimp { -namespace engine { - -namespace { -const int kDefaultWindowWidthDip = 1; -const int kDefaultWindowHeightDip = 1; - -// TODO(haibinlu): cleanup BlimpWindows on shutdown. See crbug/540498. -typedef std::vector<BlimpWindow*> BlimpWindows; -base::LazyInstance<BlimpWindows>::Leaky g_instances = LAZY_INSTANCE_INITIALIZER; - -// Returns the default size if |size| has 0 for width and/or height; -// otherwise, returns |size|. -gfx::Size AdjustWindowSize(const gfx::Size& size) { - return size.IsEmpty() - ? gfx::Size(kDefaultWindowWidthDip, kDefaultWindowHeightDip) - : size; -} -} // namespace - -BlimpWindow::~BlimpWindow() { - BlimpWindows* instances = g_instances.Pointer(); - BlimpWindows::iterator it( - std::find(instances->begin(), instances->end(), this)); - DCHECK(it != instances->end()); - instances->erase(it); -} - -// static -void BlimpWindow::Create(content::BrowserContext* browser_context, - const GURL& url, - content::SiteInstance* site_instance, - const gfx::Size& initial_size) { - content::WebContents::CreateParams create_params(browser_context, - site_instance); - scoped_ptr<content::WebContents> web_contents( - content::WebContents::Create(create_params)); - BlimpWindow* win = DoCreate(web_contents.Pass(), initial_size); - if (!url.is_empty()) - win->LoadURL(url); -} - -void BlimpWindow::LoadURL(const GURL& url) { - content::NavigationController::LoadURLParams params(url); - params.transition_type = ui::PageTransitionFromInt( - ui::PAGE_TRANSITION_TYPED | ui::PAGE_TRANSITION_FROM_ADDRESS_BAR); - web_contents_->GetController().LoadURLWithParams(params); - web_contents_->Focus(); -} - -void BlimpWindow::AddNewContents(content::WebContents* source, - content::WebContents* new_contents, - WindowOpenDisposition disposition, - const gfx::Rect& initial_rect, - bool user_gesture, - bool* was_blocked) { - DoCreate(scoped_ptr<content::WebContents>(new_contents), initial_rect.size()); -} - -content::WebContents* BlimpWindow::OpenURLFromTab( - content::WebContents* source, - const content::OpenURLParams& params) { - // CURRENT_TAB is the only one we implement for now. - if (params.disposition != CURRENT_TAB) - return nullptr; - // TOOD(haibinlu): add helper method to get LoadURLParams from OpenURLParams. - content::NavigationController::LoadURLParams load_url_params(params.url); - load_url_params.source_site_instance = params.source_site_instance; - load_url_params.referrer = params.referrer; - load_url_params.frame_tree_node_id = params.frame_tree_node_id; - load_url_params.transition_type = params.transition; - load_url_params.extra_headers = params.extra_headers; - load_url_params.should_replace_current_entry = - params.should_replace_current_entry; - - if (params.transferred_global_request_id != content::GlobalRequestID()) { - load_url_params.is_renderer_initiated = params.is_renderer_initiated; - load_url_params.transferred_global_request_id = - params.transferred_global_request_id; - } else if (params.is_renderer_initiated) { - load_url_params.is_renderer_initiated = true; - } - - source->GetController().LoadURLWithParams(load_url_params); - return source; -} - -void BlimpWindow::RequestToLockMouse(content::WebContents* web_contents, - bool user_gesture, - bool last_unlocked_by_target) { - web_contents->GotResponseToLockMouseRequest(true); -} - -void BlimpWindow::CloseContents(content::WebContents* source) { - delete this; -} - -void BlimpWindow::ActivateContents(content::WebContents* contents) { - contents->GetRenderViewHost()->Focus(); -} - -void BlimpWindow::DeactivateContents(content::WebContents* contents) { - contents->GetRenderViewHost()->Blur(); -} - -BlimpWindow::BlimpWindow(scoped_ptr<content::WebContents> web_contents) - : web_contents_(web_contents.Pass()) { - web_contents_->SetDelegate(this); - g_instances.Get().push_back(this); -} - -// static -BlimpWindow* BlimpWindow::DoCreate( - scoped_ptr<content::WebContents> web_contents, - const gfx::Size& initial_size) { - BlimpWindow* win = new BlimpWindow(web_contents.Pass()); - content::RenderWidgetHostView* host_view = - win->web_contents_->GetRenderWidgetHostView(); - if (host_view) - host_view->SetSize(AdjustWindowSize(initial_size)); - return win; -} - -} // namespace engine -} // namespace blimp
diff --git a/blimp/engine/browser/blimp_window.h b/blimp/engine/browser/blimp_window.h deleted file mode 100644 index fadf3b63..0000000 --- a/blimp/engine/browser/blimp_window.h +++ /dev/null
@@ -1,79 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -#ifndef BLIMP_ENGINE_BROWSER_BLIMP_WINDOW_H_ -#define BLIMP_ENGINE_BROWSER_BLIMP_WINDOW_H_ - -#include <vector> - -#include "base/lazy_instance.h" -#include "base/macros.h" -#include "base/memory/scoped_ptr.h" -#include "content/public/browser/web_contents_delegate.h" -#include "content/public/browser/web_contents_observer.h" -#include "ui/gfx/geometry/size.h" - -namespace content { -class BrowserContext; -class SiteInstance; -class WebContents; -} - -class GURL; - -namespace blimp { -namespace engine { - -// Owns and controls a WebContents instance corresponding to a window on -// Blimp client. -class BlimpWindow : public content::WebContentsDelegate { - public: - // This also unregisters itself with a singleton registry. - ~BlimpWindow() override; - - // Creates a new blimp window with |initial_size| and navigates to the |url|. - // Caller retains ownership of |browser_context| and |site_instance| and - // ensures |browser_context| and |site_instance| outlives BlimpWindow. - static void Create(content::BrowserContext* browser_context, - const GURL& url, - content::SiteInstance* site_instance, - const gfx::Size& initial_size); - - // Navigates to |url|. - void LoadURL(const GURL& url); - - // content::WebContentsDelegate implementation. - content::WebContents* OpenURLFromTab( - content::WebContents* source, - const content::OpenURLParams& params) override; - void AddNewContents(content::WebContents* source, - content::WebContents* new_contents, - WindowOpenDisposition disposition, - const gfx::Rect& initial_rect, - bool user_gesture, - bool* was_blocked) override; - void RequestToLockMouse(content::WebContents* web_contents, - bool user_gesture, - bool last_unlocked_by_target) override; - void CloseContents(content::WebContents* source) override; - void ActivateContents(content::WebContents* contents) override; - void DeactivateContents(content::WebContents* contents) override; - - private: - // The newly created instance registers itself with a singleton registry. - explicit BlimpWindow(scoped_ptr<content::WebContents> web_contents); - - // Helper to create a new BlimpWindow given |web_contents|. - // The newly window is owned by a singleton registry. - static BlimpWindow* DoCreate(scoped_ptr<content::WebContents> web_contents, - const gfx::Size& initial_size); - - scoped_ptr<content::WebContents> web_contents_; - - DISALLOW_COPY_AND_ASSIGN(BlimpWindow); -}; - -} // namespace engine -} // namespace blimp - -#endif // BLIMP_ENGINE_BROWSER_BLIMP_WINDOW_H_
diff --git a/blimp/engine/ui/blimp_screen.cc b/blimp/engine/ui/blimp_screen.cc index 2eba20f3..02829679 100644 --- a/blimp/engine/ui/blimp_screen.cc +++ b/blimp/engine/ui/blimp_screen.cc
@@ -10,13 +10,14 @@ namespace { const int64 kDisplayId = 1; -const int kDefaultDisplayWidth = 1; -const int kDefaultDisplayHeight = 1; const float kDefaultScale = 1.0f; const int kNumDisplays = 1; } // namespace +const int BlimpScreen::kDefaultDisplayWidth = 800; +const int BlimpScreen::kDefaultDisplayHeight = 600; + BlimpScreen::BlimpScreen() : display_(kDisplayId) { display_.SetScaleAndBounds( kDefaultScale, gfx::Rect(kDefaultDisplayWidth, kDefaultDisplayHeight));
diff --git a/blimp/engine/ui/blimp_screen.h b/blimp/engine/ui/blimp_screen.h index 99858b8a..499e3285d 100644 --- a/blimp/engine/ui/blimp_screen.h +++ b/blimp/engine/ui/blimp_screen.h
@@ -35,6 +35,9 @@ void AddObserver(gfx::DisplayObserver* observer) override; void RemoveObserver(gfx::DisplayObserver* observer) override; + static const int kDefaultDisplayWidth; + static const int kDefaultDisplayHeight; + private: gfx::Display display_;
diff --git a/blimp/net/BUILD.gn b/blimp/net/BUILD.gn index 5a1784c..05a1ff3 100644 --- a/blimp/net/BUILD.gn +++ b/blimp/net/BUILD.gn
@@ -6,6 +6,8 @@ component("blimp_net") { sources = [ + "blimp_client_session.cc", + "blimp_client_session.h", "blimp_message_dispatcher.cc", "blimp_message_dispatcher.h", "blimp_message_receiver.h",
diff --git a/blimp/net/blimp_client_session.cc b/blimp/net/blimp_client_session.cc new file mode 100644 index 0000000..c412be22 --- /dev/null +++ b/blimp/net/blimp_client_session.cc
@@ -0,0 +1,13 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "blimp/net/blimp_client_session.h" + +namespace blimp { + +BlimpClientSession::BlimpClientSession() {} + +BlimpClientSession::~BlimpClientSession() {} + +} // namespace blimp
diff --git a/blimp/net/blimp_client_session.h b/blimp/net/blimp_client_session.h new file mode 100644 index 0000000..7cde1537 --- /dev/null +++ b/blimp/net/blimp_client_session.h
@@ -0,0 +1,23 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BLIMP_NET_BLIMP_CLIENT_SESSION_H_ +#define BLIMP_NET_BLIMP_CLIENT_SESSION_H_ + +#include "base/macros.h" + +namespace blimp { + +class BlimpClientSession { + public: + BlimpClientSession(); + ~BlimpClientSession(); + + private: + DISALLOW_COPY_AND_ASSIGN(BlimpClientSession); +}; + +} // namespace blimp + +#endif // BLIMP_NET_BLIMP_CLIENT_SESSION_H_
diff --git a/build/android/copy_ex.gypi b/build/android/copy_ex.gypi index 8c49d24..bae0dd24 100644 --- a/build/android/copy_ex.gypi +++ b/build/android/copy_ex.gypi
@@ -6,11 +6,9 @@ # # Variables: # dest_path - directory to copy files to. -# src_files - optional, a list of files to copy without changing name. +# src_files - a list of files to copy. # clear - optional, if set, clear directory before copying files. -# renaming_sources - optional, a list of files to copy and rename. -# renaming_destinations - optional, a list of new file names corresponding to -# renaming_sources. +# stamp - optional, path to touch on success. # # Exmaple # { @@ -20,10 +18,6 @@ # 'dest_path': 'apk/assets/path', # 'src_files': ['path1/fr.pak'], # 'clear': 1, -# # path2/old1 and path3/old2 will be copied to apk/assets/path and -# # renamed to new1, new2 respectly. -# 'renaming_sources': ['path2/old1', 'path3/old2'], -# 'renaming_destinations': ['new1', 'new2'], # }, # 'includes': [ '../build/android/copy_ex.gypi' ], # }, @@ -31,49 +25,35 @@ { 'variables': { 'clear%': 0, - 'src_files%': [], - 'renaming_sources%': [], - 'renaming_destinations%': [], + 'stamp%': '', }, 'actions': [{ 'action_name': '<(_target_name)_copy_ex', 'variables': { 'additional_args':[], - 'local_inputs': [], - 'dest_files': [], 'conditions': [ ['clear == 1', { 'additional_args': ['--clear'], }], - ['src_files != []', { - 'additional_args': ['--files', '<(src_files)'], - 'local_inputs': ['<@(src_files)'], - # src_files will be used to generate destination files path for - # outputs. - 'dest_files': ['<@(src_files)'], - }], - ['renaming_sources != []', { - 'additional_args': [ - '--renaming-sources', '<(renaming_sources)', - '--renaming-destinations', '<(renaming_destinations)' - ], - 'local_inputs': ['<@(renaming_sources)'], - 'dest_files': ['<@(renaming_destinations)'], + ['stamp != ""', { + 'additional_args': ['--stamp', '<(stamp)'], }], ], }, 'inputs': [ '<(DEPTH)/build/android/gyp/copy_ex.py', '<(DEPTH)/build/android/gyp/generate_copy_ex_outputs.py', - '<@(local_inputs)', + '<@(src_files)', ], 'outputs': [ - '<!@pymod_do_main(generate_copy_ex_outputs --dest-path <(dest_path) --src-files <(dest_files))', + '<(stamp)', + '<!@pymod_do_main(generate_copy_ex_outputs --dest-path <(dest_path) --src-files <(src_files))' ], 'action': [ 'python', '<(DEPTH)/build/android/gyp/copy_ex.py', '--dest', '<(dest_path)', - '<@(additional_args)', + '--files', '<(src_files)', + '<(additional_args)', ], }], }
diff --git a/build/android/gyp/copy_ex.py b/build/android/gyp/copy_ex.py index f99e71d..a474e770 100755 --- a/build/android/gyp/copy_ex.py +++ b/build/android/gyp/copy_ex.py
@@ -6,7 +6,6 @@ """Copies files to a directory.""" -import itertools import optparse import os import shutil @@ -24,49 +23,6 @@ result.extend([os.path.join(root[len(dirname):], f) for f in files]) return result -def CopyFile(f, dest, deps): - """Copy file or directory and update deps.""" - if os.path.isdir(f): - shutil.copytree(f, os.path.join(dest, os.path.basename(f))) - deps.extend(_get_all_files(f)) - else: - shutil.copy(f, dest) - deps.append(f) - -def DoCopy(options, deps): - """Copy files or directories given in options.files and update deps.""" - files = list(itertools.chain.from_iterable(build_utils.ParseGypList(f) - for f in options.files)) - - for f in files: - if os.path.isdir(f): - if not options.clear: - print ('To avoid stale files you must use --clear when copying ' - 'directories') - sys.exit(-1) - else: - CopyFile(f, options.dest, deps) - -def DoRenaming(options, deps): - """Copy and rename files given in options.renaming_sources and update deps.""" - src_files = list(itertools.chain.from_iterable( - build_utils.ParseGypList(f) - for f in options.renaming_sources)) - - dest_files = list(itertools.chain.from_iterable( - build_utils.ParseGypList(f) - for f in options.renaming_destinations)) - - if (len(src_files) != len(dest_files)): - print('Renaming source and destination files not match.') - sys.exit(-1) - - for src, dest in itertools.izip(src_files, dest_files): - if os.path.isdir(src): - print ('renaming diretory is not supported.') - sys.exit(-1) - else: - CopyFile(src, os.path.join(options.dest, dest), deps) def main(args): args = build_utils.ExpandFileArgs(args) @@ -82,14 +38,6 @@ 'before copying files to it. This is highly recommended to ' 'ensure that no stale files are left in the directory.') parser.add_option('--stamp', help='Path to touch on success.') - parser.add_option('--renaming-sources', - action='append', - help='List of files need to be renamed while being ' - 'copied to dest directory') - parser.add_option('--renaming-destinations', - action='append', - help='List of destination file name without path, the ' - 'number of elements must match rename-sources.') options, _ = parser.parse_args(args) @@ -97,13 +45,23 @@ build_utils.DeleteDirectory(options.dest) build_utils.MakeDirectory(options.dest) + files = [] + for file_arg in options.files: + files += build_utils.ParseGypList(file_arg) + deps = [] - if options.files: - DoCopy(options, deps) - - if options.renaming_sources: - DoRenaming(options, deps) + for f in files: + if os.path.isdir(f): + if not options.clear: + print ('To avoid stale files you must use --clear when copying ' + 'directories') + sys.exit(-1) + shutil.copytree(f, os.path.join(options.dest, os.path.basename(f))) + deps.extend(_get_all_files(f)) + else: + shutil.copy(f, options.dest) + deps.append(f) if options.depfile: build_utils.WriteDepfile(
diff --git a/build/android/incremental_install/BUILD.gn b/build/android/incremental_install/BUILD.gn index 1b54701..ab39e4c2 100644 --- a/build/android/incremental_install/BUILD.gn +++ b/build/android/incremental_install/BUILD.gn
@@ -9,6 +9,7 @@ dex_path = "$target_gen_dir/bootstrap.dex" java_files = [ "java/org/chromium/incrementalinstall/BootstrapApplication.java", + "java/org/chromium/incrementalinstall/BootstrapInstrumentation.java", "java/org/chromium/incrementalinstall/ClassLoaderPatcher.java", "java/org/chromium/incrementalinstall/LockFile.java", "java/org/chromium/incrementalinstall/Reflect.java",
diff --git a/build/android/incremental_install/__init__.py b/build/android/incremental_install/__init__.py new file mode 100644 index 0000000..1aaf0e1 --- /dev/null +++ b/build/android/incremental_install/__init__.py
@@ -0,0 +1,4 @@ +# 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. +
diff --git a/build/android/incremental_install/create_install_script.py b/build/android/incremental_install/create_install_script.py index 614cbb7..5040a565 100755 --- a/build/android/incremental_install/create_install_script.py +++ b/build/android/incremental_install/create_install_script.py
@@ -28,20 +28,40 @@ import subprocess import sys -def main(): + +def _ResolvePath(path): script_directory = os.path.dirname(__file__) + return os.path.abspath(os.path.join(script_directory, path)) - def resolve_path(path): - return os.path.abspath(os.path.join(script_directory, path)) - cmd_path = resolve_path({cmd_path}) - cmd_args = [cmd_path] + {cmd_args} - cmd_path_args = {cmd_path_args} - for arg, path in cmd_path_args: - if arg: - cmd_args.append(arg) - cmd_args.append(resolve_path(path)) +# Exported to allow test runner to be able to install incremental apks. +def GetInstallParameters(): + apk_path = {apk_path} + lib_dir = {lib_dir} + dex_files = {dex_files} + splits = {splits} + return dict(apk_path=_ResolvePath(apk_path), + dex_files=[_ResolvePath(p) for p in dex_files], + lib_dir=_ResolvePath(lib_dir), + splits=[_ResolvePath(p) for p in splits]) + + +def main(): + output_directory = {output_directory} + cmd_path = {cmd_path} + params = GetInstallParameters() + cmd_args = [ + _ResolvePath(cmd_path), + '--output-directory', _ResolvePath(output_directory), + ] + if params['lib_dir']: + cmd_args.extend(('--lib-dir', params['lib_dir'])) + for dex_path in params['dex_files']: + cmd_args.extend(('--dex-file', dex_path)) + for split in params['splits']: + cmd_args.extend(('--split', split)) + cmd_args.append(params['apk_path']) return subprocess.call(cmd_args + sys.argv[1:]) if __name__ == '__main__': @@ -87,32 +107,23 @@ options = _ParseArgs(args) def relativize(path): - return os.path.relpath(path, os.path.dirname(options.script_output_path)) + script_dir = os.path.dirname(options.script_output_path) + return path and os.path.relpath(path, script_dir) installer_path = os.path.join(constants.DIR_SOURCE_ROOT, 'build', 'android', 'incremental_install', 'installer.py') - installer_path = relativize(installer_path) - - path_args = [ - ('--output-directory', relativize(options.output_directory)), - (None, relativize(options.apk_path)), - ] - - if options.lib_dir: - path_args.append(('--lib-dir', relativize(options.lib_dir))) - - if options.dex_files: - for dex_file in options.dex_files: - path_args.append(('--dex-file', relativize(dex_file))) - - for split_arg in options.splits: - path_args.append(('--split', relativize(split_arg))) + pformat = pprint.pformat + template_args = { + 'cmd_path': pformat(relativize(installer_path)), + 'apk_path': pformat(relativize(options.apk_path)), + 'output_directory': pformat(relativize(options.output_directory)), + 'lib_dir': pformat(relativize(options.lib_dir)), + 'dex_files': pformat([relativize(p) for p in options.dex_files]), + 'splits': pformat([relativize(p) for p in options.splits]), + } with open(options.script_output_path, 'w') as script: - script.write(SCRIPT_TEMPLATE.format( - cmd_path=pprint.pformat(installer_path), - cmd_args='[]', - cmd_path_args=pprint.pformat(path_args))) + script.write(SCRIPT_TEMPLATE.format(**template_args)) os.chmod(options.script_output_path, 0750)
diff --git a/build/android/incremental_install/generate_android_manifest.py b/build/android/incremental_install/generate_android_manifest.py index 17eabd4d..163b4c3 100755 --- a/build/android/incremental_install/generate_android_manifest.py +++ b/build/android/incremental_install/generate_android_manifest.py
@@ -21,8 +21,10 @@ ElementTree.register_namespace('android', _ANDROID_NAMESPACE) _INCREMENTAL_APP_NAME = 'org.chromium.incrementalinstall.BootstrapApplication' -_META_DATA_NAME = 'incremental-install-real-app' +_META_DATA_APP_NAME = 'incremental-install-real-app' +_META_DATA_INSTRUMENTATION_NAME = 'incremental-install-real-instrumentation' _DEFAULT_APPLICATION_CLASS = 'android.app.Application' +_DEFAULT_INSTRUMENTATION_CLASS = 'android.app.Instrumentation' def _AddNamespace(name): @@ -45,6 +47,12 @@ return parser.parse_args() +def _CreateMetaData(parent, name, value): + meta_data_node = ElementTree.SubElement(parent, 'meta-data') + meta_data_node.set(_AddNamespace('name'), name) + meta_data_node.set(_AddNamespace('value'), value) + + def _ProcessManifest(main_manifest, disable_isolated_processes): """Returns a transformed AndroidManifest.xml for use with _incremental apks. @@ -68,10 +76,18 @@ real_app_class = app_node.get(_AddNamespace('name'), _DEFAULT_APPLICATION_CLASS) app_node.set(_AddNamespace('name'), _INCREMENTAL_APP_NAME) + _CreateMetaData(app_node, _META_DATA_APP_NAME, real_app_class) - meta_data_node = ElementTree.SubElement(app_node, 'meta-data') - meta_data_node.set(_AddNamespace('name'), _META_DATA_NAME) - meta_data_node.set(_AddNamespace('value'), real_app_class) + # Seems to be a bug in ElementTree, as doc.find() doesn't work here. + instrumentation_nodes = doc.findall('instrumentation') + if instrumentation_nodes: + instrumentation_node = instrumentation_nodes[0] + real_instrumentation_class = instrumentation_node.get(_AddNamespace('name')) + instrumentation_node.set(_AddNamespace('name'), + _DEFAULT_INSTRUMENTATION_CLASS) + _CreateMetaData(app_node, _META_DATA_INSTRUMENTATION_NAME, + real_instrumentation_class) + return ElementTree.tostring(doc, encoding='UTF-8')
diff --git a/build/android/incremental_install/installer.py b/build/android/incremental_install/installer.py index 40d2d7b6..b5ed5ce 100755 --- a/build/android/incremental_install/installer.py +++ b/build/android/incremental_install/installer.py
@@ -24,8 +24,10 @@ from pylib.utils import run_tests_helper from pylib.utils import time_profile -sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir, 'gyp')) +prev_sys_path = list(sys.path) +sys.path.insert(0, os.path.join(os.path.dirname(__file__), os.pardir, 'gyp')) from util import build_utils +sys.path = prev_sys_path def _TransformDexPaths(paths): @@ -46,6 +48,142 @@ return timer +def _GetDeviceIncrementalDir(package): + """Returns the device path to put incremental files for the given package.""" + return '/data/local/tmp/incremental-app-%s' % package + + +def Uninstall(device, package): + """Uninstalls and removes all incremental files for the given package.""" + main_timer = time_profile.TimeProfile() + device.Uninstall(package) + device.RunShellCommand(['rm', '-rf', _GetDeviceIncrementalDir(package)], + check_return=True) + logging.info('Uninstall took %s seconds.', main_timer.GetDelta()) + + +def Install(device, apk, split_globs=None, lib_dir=None, dex_files=None, + enable_device_cache=True, use_concurrency=True): + """Installs the given incremental apk and all required supporting files. + + Args: + device: A DeviceUtils instance. + apk: The path to the apk, or an ApkHelper instance. + split_globs: Glob patterns for any required apk splits (optional). + lib_dir: Directory containing the app's native libraries (optional). + dex_files: List of .dex.jar files that comprise the app's Dalvik code. + enable_device_cache: Whether to enable on-device caching of checksums. + use_concurrency: Whether to speed things up using multiple threads. + """ + main_timer = time_profile.TimeProfile() + install_timer = time_profile.TimeProfile() + push_native_timer = time_profile.TimeProfile() + push_dex_timer = time_profile.TimeProfile() + + apk = apk_helper.ToHelper(apk) + apk_package = apk.GetPackageName() + device_incremental_dir = _GetDeviceIncrementalDir(apk_package) + + # Install .apk(s) if any of them have changed. + def do_install(): + install_timer.Start() + if split_globs: + splits = [] + for split_glob in split_globs: + splits.extend((f for f in glob.glob(split_glob))) + device.InstallSplitApk(apk, splits, reinstall=True, + allow_cached_props=True, permissions=()) + else: + device.Install(apk, reinstall=True, permissions=()) + install_timer.Stop(log=False) + + # Push .so and .dex files to the device (if they have changed). + def do_push_files(): + if lib_dir: + push_native_timer.Start() + device_lib_dir = posixpath.join(device_incremental_dir, 'lib') + device.PushChangedFiles([(lib_dir, device_lib_dir)], + delete_device_stale=True) + push_native_timer.Stop(log=False) + + if dex_files: + push_dex_timer.Start() + # Put all .dex files to be pushed into a temporary directory so that we + # can use delete_device_stale=True. + with build_utils.TempDir() as temp_dir: + device_dex_dir = posixpath.join(device_incremental_dir, 'dex') + # Ensure no two files have the same name. + transformed_names = _TransformDexPaths(dex_files) + for src_path, dest_name in zip(dex_files, transformed_names): + shutil.copyfile(src_path, os.path.join(temp_dir, dest_name)) + device.PushChangedFiles([(temp_dir, device_dex_dir)], + delete_device_stale=True) + push_dex_timer.Stop(log=False) + + def check_selinux(): + # Samsung started using SELinux before Marshmallow. There may be even more + # cases where this is required... + has_selinux = (device.build_version_sdk >= version_codes.MARSHMALLOW or + device.GetProp('selinux.policy_version')) + if has_selinux and apk.HasIsolatedProcesses(): + raise Exception('Cannot use incremental installs on versions of Android ' + 'where isoloated processes cannot access the filesystem ' + '(this includes Android M+, and Samsung L+) without ' + 'first disabling isoloated processes.\n' + 'To do so, use GN arg:\n' + ' disable_incremental_isolated_processes=true') + + cache_path = '%s/files-cache.json' % device_incremental_dir + def restore_cache(): + if not enable_device_cache: + logging.info('Ignoring device cache') + return + # Delete the cached file so that any exceptions cause the next attempt + # to re-compute md5s. + cmd = 'P=%s;cat $P 2>/dev/null && rm $P' % cache_path + lines = device.RunShellCommand(cmd, check_return=False, large_output=True) + if lines: + device.LoadCacheData(lines[0]) + else: + logging.info('Device cache not found: %s', cache_path) + + def save_cache(): + cache_data = device.DumpCacheData() + device.WriteFile(cache_path, cache_data) + + # Create 2 lock files: + # * install.lock tells the app to pause on start-up (until we release it). + # * firstrun.lock is used by the app to pause all secondary processes until + # the primary process finishes loading the .dex / .so files. + def create_lock_files(): + # Creates or zeros out lock files. + cmd = ('D="%s";' + 'mkdir -p $D &&' + 'echo -n >$D/install.lock 2>$D/firstrun.lock') + device.RunShellCommand(cmd % device_incremental_dir, check_return=True) + + # The firstrun.lock is released by the app itself. + def release_installer_lock(): + device.RunShellCommand('echo > %s/install.lock' % device_incremental_dir, + check_return=True) + + # Concurrency here speeds things up quite a bit, but DeviceUtils hasn't + # been designed for multi-threading. Enabling only because this is a + # developer-only tool. + setup_timer = _Execute( + use_concurrency, create_lock_files, restore_cache, check_selinux) + + _Execute(use_concurrency, do_install, do_push_files) + + finalize_timer = _Execute(use_concurrency, release_installer_lock, save_cache) + + logging.info( + 'Took %s seconds (setup=%s, install=%s, libs=%s, dex=%s, finalize=%s)', + main_timer.GetDelta(), setup_timer.GetDelta(), install_timer.GetDelta(), + push_native_timer.GetDelta(), push_dex_timer.GetDelta(), + finalize_timer.GetDelta()) + + def main(): parser = argparse.ArgumentParser() parser.add_argument('apk_path', @@ -94,11 +232,6 @@ if args.output_directory: constants.SetOutputDirectory(args.output_directory) - main_timer = time_profile.TimeProfile() - install_timer = time_profile.TimeProfile() - push_native_timer = time_profile.TimeProfile() - push_dex_timer = time_profile.TimeProfile() - if args.device: # Retries are annoying when commands fail for legitimate reasons. Might want # to enable them if this is ever used on bots though. @@ -121,117 +254,14 @@ msg += ' %s (%s)\n' % (d, desc) raise Exception(msg) - apk = apk_helper.ApkHelper(args.apk_path) - apk_package = apk.GetPackageName() - device_incremental_dir = '/data/local/tmp/incremental-app-%s' % apk_package - + apk = apk_helper.ToHelper(args.apk_path) if args.uninstall: - device.Uninstall(apk_package) - device.RunShellCommand(['rm', '-rf', device_incremental_dir], - check_return=True) - logging.info('Uninstall took %s seconds.', main_timer.GetDelta()) - return - - # Install .apk(s) if any of them have changed. - def do_install(): - install_timer.Start() - if args.splits: - splits = [] - for split_glob in args.splits: - splits.extend((f for f in glob.glob(split_glob))) - device.InstallSplitApk(apk, splits, reinstall=True, - allow_cached_props=True, permissions=()) - else: - device.Install(apk, reinstall=True, permissions=()) - install_timer.Stop(log=False) - - # Push .so and .dex files to the device (if they have changed). - def do_push_files(): - if args.lib_dir: - push_native_timer.Start() - device_lib_dir = posixpath.join(device_incremental_dir, 'lib') - device.PushChangedFiles([(args.lib_dir, device_lib_dir)], - delete_device_stale=True) - push_native_timer.Stop(log=False) - - if args.dex_files: - push_dex_timer.Start() - # Put all .dex files to be pushed into a temporary directory so that we - # can use delete_device_stale=True. - with build_utils.TempDir() as temp_dir: - device_dex_dir = posixpath.join(device_incremental_dir, 'dex') - # Ensure no two files have the same name. - transformed_names = _TransformDexPaths(args.dex_files) - for src_path, dest_name in zip(args.dex_files, transformed_names): - shutil.copyfile(src_path, os.path.join(temp_dir, dest_name)) - device.PushChangedFiles([(temp_dir, device_dex_dir)], - delete_device_stale=True) - push_dex_timer.Stop(log=False) - - def check_selinux(): - # Samsung started using SELinux before Marshmallow. There may be even more - # cases where this is required... - has_selinux = (device.build_version_sdk >= version_codes.MARSHMALLOW or - device.GetProp('selinux.policy_version')) - if has_selinux and apk.HasIsolatedProcesses(): - raise Exception('Cannot use incremental installs on versions of Android ' - 'where isoloated processes cannot access the filesystem ' - '(this includes Android M+, and Samsung L+) without ' - 'first disabling isoloated processes.\n' - 'To do so, use GN arg:\n' - ' disable_incremental_isolated_processes=true') - - cache_path = '%s/files-cache.json' % device_incremental_dir - def restore_cache(): - if not args.cache: - logging.info('Ignoring device cache') - return - # Delete the cached file so that any exceptions cause the next attempt - # to re-compute md5s. - cmd = 'P=%s;cat $P 2>/dev/null && rm $P' % cache_path - lines = device.RunShellCommand(cmd, check_return=False, large_output=True) - if lines: - device.LoadCacheData(lines[0]) - else: - logging.info('Device cache not found: %s', cache_path) - - def save_cache(): - cache_data = device.DumpCacheData() - device.WriteFile(cache_path, cache_data) - - # Create 2 lock files: - # * install.lock tells the app to pause on start-up (until we release it). - # * firstrun.lock is used by the app to pause all secondary processes until - # the primary process finishes loading the .dex / .so files. - def create_lock_files(): - # Creates or zeros out lock files. - cmd = ('D="%s";' - 'mkdir -p $D &&' - 'echo -n >$D/install.lock 2>$D/firstrun.lock') - device.RunShellCommand(cmd % device_incremental_dir, check_return=True) - - # The firstrun.lock is released by the app itself. - def release_installer_lock(): - device.RunShellCommand('echo > %s/install.lock' % device_incremental_dir, - check_return=True) - - # Concurrency here speeds things up quite a bit, but DeviceUtils hasn't - # been designed for multi-threading. Enabling only because this is a - # developer-only tool. - setup_timer = _Execute( - args.threading, create_lock_files, restore_cache, check_selinux) - - _Execute(args.threading, do_install, do_push_files) - - finalize_timer = _Execute(args.threading, release_installer_lock, save_cache) - - logging.info( - 'Took %s seconds (setup=%s, install=%s, libs=%s, dex=%s, finalize=%s)', - main_timer.GetDelta(), setup_timer.GetDelta(), install_timer.GetDelta(), - push_native_timer.GetDelta(), push_dex_timer.GetDelta(), - finalize_timer.GetDelta()) + Uninstall(device, apk.GetPackageName()) + else: + Install(device, apk, split_globs=args.splits, lib_dir=args.lib_dir, + dex_files=args.dex_files, enable_device_cache=args.cache, + use_concurrency=args.threading) if __name__ == '__main__': sys.exit(main()) -
diff --git a/build/android/incremental_install/java/org/chromium/incrementalinstall/BootstrapApplication.java b/build/android/incremental_install/java/org/chromium/incrementalinstall/BootstrapApplication.java index 81e06a2..e932c1bd 100644 --- a/build/android/incremental_install/java/org/chromium/incrementalinstall/BootstrapApplication.java +++ b/build/android/incremental_install/java/org/chromium/incrementalinstall/BootstrapApplication.java
@@ -5,10 +5,13 @@ package org.chromium.incrementalinstall; import android.app.Application; +import android.app.Instrumentation; +import android.content.ComponentName; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; +import android.os.Bundle; import android.util.Log; import java.io.File; @@ -18,17 +21,23 @@ /** * An Application that replaces itself with another Application (as defined in - * the "incremental-install-real-app" meta-data tag within the - * AndroidManifest.xml). It loads the other application only after side-loading - * its .so and .dex files from /data/local/tmp. + * an AndroidManifext.xml meta-data tag). It loads the other application only + * after side-loading its .so and .dex files from /data/local/tmp. + * + * This class is highly dependent on the private implementation details of + * Android's ActivityThread.java. However, it has been tested to work with + * JellyBean through Marshmallow. */ public final class BootstrapApplication extends Application { private static final String TAG = "cr.incrementalinstall"; private static final String MANAGED_DIR_PREFIX = "/data/local/tmp/incremental-app-"; private static final String REAL_APP_META_DATA_NAME = "incremental-install-real-app"; + private static final String REAL_INSTRUMENTATION_META_DATA_NAME = + "incremental-install-real-instrumentation"; private ClassLoaderPatcher mClassLoaderPatcher; private Application mRealApplication; + private Instrumentation mRealInstrumentation; private Object mStashedProviderList; private Object mActivityThread; @@ -65,10 +74,25 @@ LockFile.clearInstallerLock(firstRunLockFile); } + Bundle metadata = getManifestMetadata(); + // mInstrumentationAppDir is one of a set of fields that is initialized only when + // instrumentation is active. + if (Reflect.getField(mActivityThread, "mInstrumentationAppDir") != null) { + initInstrumentation(metadata.getString(REAL_INSTRUMENTATION_META_DATA_NAME)); + } else { + Log.i(TAG, "No instrumentation active."); + } + + // Even when instrumentation is not enabled, ActivityThread uses a default + // Instrumentation instance internally. We hook it here in order to hook into the + // call to Instrumentation.onCreate(). + Reflect.setField(mActivityThread, "mInstrumentation", + new BootstrapInstrumentation(this)); + // attachBaseContext() is called from ActivityThread#handleBindApplication() and // Application#mApplication is changed right after we return. Thus, we cannot swap // the Application instances until onCreate() is called. - String realApplicationName = getRealApplicationName(); + String realApplicationName = metadata.getString(REAL_APP_META_DATA_NAME); Log.i(TAG, "Instantiating " + realApplicationName); mRealApplication = (Application) Reflect.newInstance(Class.forName(realApplicationName)); @@ -79,7 +103,49 @@ // class being installed, so temporarily pretend there are no providers, and then // instantiate them explicitly within onCreate(). disableContentProviders(); - Log.i(TAG, "Waiting for onCreate"); + Log.i(TAG, "Waiting for Instrumentation.onCreate"); + } catch (Exception e) { + throw new RuntimeException("Incremental install failed.", e); + } + } + + /** + * Instantiates and initializes mRealInstrumentation (the real Instrumentation class). + */ + private void initInstrumentation(String realInstrumentationName) + throws ReflectiveOperationException { + Log.i(TAG, "Instantiating instrumentation " + realInstrumentationName); + mRealInstrumentation = (Instrumentation) Reflect.newInstance( + Class.forName(realInstrumentationName)); + Instrumentation oldInstrumentation = + (Instrumentation) Reflect.getField(mActivityThread, "mInstrumentation"); + + // Initialize the fields that are set by Instrumentation.init(). + String[] initFields = {"mThread", "mMessageQueue", "mInstrContext", "mAppContext", + "mWatcher", "mUiAutomationConnection"}; + for (String fieldName : initFields) { + Reflect.setField(mRealInstrumentation, fieldName, + Reflect.getField(oldInstrumentation, fieldName)); + } + // But make sure the correct ComponentName is used. + ComponentName newName = new ComponentName( + oldInstrumentation.getComponentName().getPackageName(), realInstrumentationName); + Reflect.setField(mRealInstrumentation, "mComponent", newName); + } + + /** + * Called by BootstrapInstrumentation from Instrumentation.onCreate(). + * This happens regardless of whether or not instrumentation is enabled. + */ + void onInstrumentationCreate(Bundle arguments) { + Log.i(TAG, "Instrumentation.onCreate() called. Swapping references."); + try { + swapApplicationReferences(); + enableContentProviders(); + if (mRealInstrumentation != null) { + Reflect.setField(mActivityThread, "mInstrumentation", mRealInstrumentation); + mRealInstrumentation.onCreate(arguments); + } } catch (Exception e) { throw new RuntimeException("Incremental install failed.", e); } @@ -89,10 +155,7 @@ public void onCreate() { super.onCreate(); try { - Log.i(TAG, "onCreate() called. Swapping Application references"); - swapApplicationReferences(); - enableContentProviders(); - Log.i(TAG, "Calling onCreate"); + Log.i(TAG, "Application.onCreate() called."); mRealApplication.onCreate(); } catch (Exception e) { throw new RuntimeException("Incremental install failed.", e); @@ -103,10 +166,10 @@ * Returns the class name of the real Application class (recorded in the * AndroidManifest.xml) */ - private String getRealApplicationName() throws NameNotFoundException { + private Bundle getManifestMetadata() throws NameNotFoundException { ApplicationInfo appInfo = getPackageManager().getApplicationInfo(getPackageName(), PackageManager.GET_META_DATA); - return appInfo.metaData.getString(REAL_APP_META_DATA_NAME); + return appInfo.metaData; } /**
diff --git a/build/android/incremental_install/java/org/chromium/incrementalinstall/BootstrapInstrumentation.java b/build/android/incremental_install/java/org/chromium/incrementalinstall/BootstrapInstrumentation.java new file mode 100644 index 0000000..f197406 --- /dev/null +++ b/build/android/incremental_install/java/org/chromium/incrementalinstall/BootstrapInstrumentation.java
@@ -0,0 +1,25 @@ +// 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.incrementalinstall; + +import android.app.Instrumentation; +import android.os.Bundle; + +/** + * Notifies BootstrapApplication of the call to Instrumentation.onCreate(). + */ +public final class BootstrapInstrumentation extends Instrumentation { + private final BootstrapApplication mApp; + + BootstrapInstrumentation(BootstrapApplication app) { + mApp = app; + } + + @Override + public void onCreate(Bundle arguments) { + super.onCreate(arguments); + mApp.onInstrumentationCreate(arguments); + } +}
diff --git a/build/android/pylib/gtest/gtest_test_instance.py b/build/android/pylib/gtest/gtest_test_instance.py index e61b89c..d276592 100644 --- a/build/android/pylib/gtest/gtest_test_instance.py +++ b/build/android/pylib/gtest/gtest_test_instance.py
@@ -138,9 +138,10 @@ self._shard_timeout = args.shard_timeout + incremental_part = '_incremental' if args.incremental_install else '' apk_path = os.path.join( constants.GetOutDirectory(), '%s_apk' % self._suite, - '%s-debug.apk' % self._suite) + '%s-debug%s.apk' % (self._suite, incremental_part)) self._exe_path = os.path.join(constants.GetOutDirectory(), self._suite) if not os.path.exists(apk_path):
diff --git a/build/android/pylib/local/device/local_device_environment.py b/build/android/pylib/local/device/local_device_environment.py index 25ef5828d..b877dbc 100644 --- a/build/android/pylib/local/device/local_device_environment.py +++ b/build/android/pylib/local/device/local_device_environment.py
@@ -32,6 +32,7 @@ self._max_tries = 1 + args.num_retries self._tool_name = args.tool self._enable_device_cache = args.enable_device_cache + self._incremental_install = args.incremental_install #override def SetUp(self): @@ -64,6 +65,10 @@ return self._devices @property + def incremental_install(self): + return self._incremental_install + + @property def parallel_devices(self): return parallelizer.SyncParallelizer(self.devices)
diff --git a/build/android/pylib/local/device/local_device_gtest_run.py b/build/android/pylib/local/device/local_device_gtest_run.py index 81d85fd..55747ac 100644 --- a/build/android/pylib/local/device/local_device_gtest_run.py +++ b/build/android/pylib/local/device/local_device_gtest_run.py
@@ -2,6 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import imp import itertools import os import posixpath @@ -9,6 +10,7 @@ from devil.android import device_errors from devil.android import device_temp_file from devil.android import ports +from incremental_install import installer from pylib import constants from pylib.gtest import gtest_test_instance from pylib.local import local_test_server_spawner @@ -85,12 +87,27 @@ self._package = test_instance.package self._runner = test_instance.runner self._permissions = test_instance.permissions - + self._suite = test_instance.suite self._component = '%s/%s' % (self._package, self._runner) self._extras = test_instance.extras - def Install(self, device): - device.Install(self._apk_helper, permissions=self._permissions) + def Install(self, device, incremental=False): + if not incremental: + device.Install(self._apk_helper, permissions=self._permissions) + return + + installer_script = os.path.join(constants.GetOutDirectory(), 'bin', + 'install_%s_apk_incremental' % self._suite) + try: + install_wrapper = imp.load_source('install_wrapper', installer_script) + except IOError: + raise Exception(('Incremental install script not found: %s\n' + 'Make sure to first build "%s_incremental"') % + (installer_script, self._suite)) + params = install_wrapper.GetInstallParameters() + + installer.Install(device, self._apk_helper, split_globs=params['splits'], + lib_dir=params['lib_dir'], dex_files=params['dex_files']) def Run(self, test, device, flags=None, **kwargs): extras = dict(self._extras) @@ -141,7 +158,8 @@ self._deps_host_path = None self._test_run = tr - def Install(self, device): + def Install(self, device, incremental=False): + assert not incremental # TODO(jbudorick): Look into merging this with normal data deps pushing if # executables become supported on nonlocal environments. host_device_tuples = [(self._exe_host_path, self._exe_device_path)] @@ -210,7 +228,7 @@ @local_device_test_run.handle_shard_failures def individual_device_set_up(dev, host_device_tuples): # Install test APK. - self._delegate.Install(dev) + self._delegate.Install(dev, incremental=self._env.incremental_install) # Push data dependencies. external_storage = dev.GetExternalStoragePath()
diff --git a/build/android/test_runner.py b/build/android/test_runner.py index a3a3a98..955e09b 100755 --- a/build/android/test_runner.py +++ b/build/android/test_runner.py
@@ -188,6 +188,8 @@ group.add_argument('--blacklist-file', help='Device blacklist file.') group.add_argument('--enable-device-cache', action='store_true', help='Cache device state to disk between runs') + group.add_argument('--incremental-install', action='store_true', + help='Use an _incremental apk.') def AddGTestOptions(parser):
diff --git a/build/config/android/internal_rules.gni b/build/config/android/internal_rules.gni index 7320db4..a64f14a4 100644 --- a/build/config/android/internal_rules.gni +++ b/build/config/android/internal_rules.gni
@@ -1531,17 +1531,6 @@ if (defined(invoker.args)) { args += invoker.args } - - if (defined(invoker.renaming_sources) && - defined(invoker.renaming_destinations)) { - sources += invoker.renaming_sources - rebased_renaming_sources = - rebase_path(invoker.renaming_sources, root_build_dir) - args += [ "--renaming-sources=$rebased_renaming_sources" ] - - renaming_destinations = invoker.renaming_destinations - args += [ "--renaming-destinations=$renaming_destinations" ] - } } } @@ -1672,6 +1661,16 @@ rebase_path(invoker.isolate_file, root_build_dir), ] } + if (defined(invoker.incremental_install) && invoker.incremental_install) { + test_runner_args += [ "--incremental-install" ] + + # These can still be overridden, but make more better defaults during + # development. + test_runner_args += [ + "--enable-device-cache", + "--num_retries=0", + ] + } generated_script = "$root_build_dir/bin/run_${_test_name}" outputs = [
diff --git a/cc/base/switches.cc b/cc/base/switches.cc index 0db15030..9a5b039 100644 --- a/cc/base/switches.cc +++ b/cc/base/switches.cc
@@ -11,6 +11,12 @@ const char kDisableThreadedAnimation[] = "disable-threaded-animation"; +// Disables the use of a cached picture for raster in the renderer, +// making raster go directly from the display item list (this is the data +// structure surfaced to tracing). This is useful for debugging to remove +// the cached picture from the pipeline to narrow down bugs. +const char kDisableCachedPictureRaster[] = "disable-cached-picture-raster"; + // Disables layer-edge anti-aliasing in the compositor. const char kDisableCompositedAntialiasing[] = "disable-composited-antialiasing"; @@ -44,9 +50,6 @@ const char kEnablePropertyTreeVerification[] = "enable-property-tree-verification"; -// Disable partial swap which is needed for some OpenGL drivers / emulators. -const char kUIDisablePartialSwap[] = "ui-disable-partial-swap"; - // Use a BeginFrame signal from browser to renderer to schedule rendering. const char kEnableBeginFrameScheduling[] = "enable-begin-frame-scheduling";
diff --git a/cc/base/switches.h b/cc/base/switches.h index 3bce14e..d72b250 100644 --- a/cc/base/switches.h +++ b/cc/base/switches.h
@@ -17,10 +17,10 @@ // Switches for the renderer compositor only. CC_EXPORT extern const char kDisableThreadedAnimation[]; +CC_EXPORT extern const char kDisableCachedPictureRaster[]; CC_EXPORT extern const char kDisableCompositedAntialiasing[]; CC_EXPORT extern const char kDisableMainFrameBeforeActivation[]; CC_EXPORT extern const char kEnableMainFrameBeforeActivation[]; -CC_EXPORT extern const char kJankInsteadOfCheckerboard[]; CC_EXPORT extern const char kTopControlsHideThreshold[]; CC_EXPORT extern const char kTopControlsShowThreshold[]; CC_EXPORT extern const char kSlowDownRasterScaleFactor[]; @@ -28,7 +28,6 @@ CC_EXPORT extern const char kEnablePropertyTreeVerification[]; // Switches for both the renderer and ui compositors. -CC_EXPORT extern const char kUIDisablePartialSwap[]; CC_EXPORT extern const char kEnableBeginFrameScheduling[]; CC_EXPORT extern const char kEnableGpuBenchmarking[];
diff --git a/cc/blink/web_content_layer_impl.cc b/cc/blink/web_content_layer_impl.cc index 4ccd763..f5ec32b 100644 --- a/cc/blink/web_content_layer_impl.cc +++ b/cc/blink/web_content_layer_impl.cc
@@ -4,6 +4,8 @@ #include "cc/blink/web_content_layer_impl.h" +#include "base/command_line.h" +#include "cc/base/switches.h" #include "cc/blink/web_display_item_list_impl.h" #include "cc/layers/picture_layer.h" #include "cc/playback/display_item_list_settings.h" @@ -18,6 +20,12 @@ namespace cc_blink { +static bool UseCachedPictureRaster() { + static bool use = !base::CommandLine::ForCurrentProcess()->HasSwitch( + cc::switches::kDisableCachedPictureRaster); + return use; +} + static blink::WebContentLayerClient::PaintingControlSetting PaintingControlToWeb( cc::ContentLayerClient::PaintingControlSetting painting_control) { @@ -54,22 +62,12 @@ layer_->layer()->SetDoubleSided(double_sided); } -void WebContentLayerImpl::PaintContents( - SkCanvas* canvas, - const gfx::Rect& clip, - cc::ContentLayerClient::PaintingControlSetting painting_control) { - if (!client_) - return; - - client_->paintContents(canvas, clip, PaintingControlToWeb(painting_control)); -} - scoped_refptr<cc::DisplayItemList> WebContentLayerImpl::PaintContentsToDisplayList( const gfx::Rect& clip, cc::ContentLayerClient::PaintingControlSetting painting_control) { cc::DisplayItemListSettings settings; - settings.use_cached_picture = true; + settings.use_cached_picture = UseCachedPictureRaster(); scoped_refptr<cc::DisplayItemList> display_list = cc::DisplayItemList::Create(clip, settings);
diff --git a/cc/blink/web_content_layer_impl.h b/cc/blink/web_content_layer_impl.h index fb0fcb7..82956b84 100644 --- a/cc/blink/web_content_layer_impl.h +++ b/cc/blink/web_content_layer_impl.h
@@ -35,9 +35,6 @@ ~WebContentLayerImpl() override; // ContentLayerClient implementation. - void PaintContents(SkCanvas* canvas, - const gfx::Rect& clip, - PaintingControlSetting painting_control) override; scoped_refptr<cc::DisplayItemList> PaintContentsToDisplayList( const gfx::Rect& clip, PaintingControlSetting painting_control) override;
diff --git a/cc/layers/content_layer_client.h b/cc/layers/content_layer_client.h index deb9d619..d56ab6e 100644 --- a/cc/layers/content_layer_client.h +++ b/cc/layers/content_layer_client.h
@@ -8,8 +8,6 @@ #include "cc/base/cc_export.h" #include "cc/playback/display_item_list.h" -class SkCanvas; - namespace gfx { class Rect; } @@ -25,10 +23,6 @@ DISPLAY_LIST_PAINTING_DISABLED }; - virtual void PaintContents(SkCanvas* canvas, - const gfx::Rect& clip, - PaintingControlSetting painting_status) = 0; - virtual scoped_refptr<DisplayItemList> PaintContentsToDisplayList( const gfx::Rect& clip, PaintingControlSetting painting_status) = 0;
diff --git a/cc/layers/picture_image_layer.cc b/cc/layers/picture_image_layer.cc index ee12933..f2caeaf 100644 --- a/cc/layers/picture_image_layer.cc +++ b/cc/layers/picture_image_layer.cc
@@ -49,14 +49,23 @@ SetNeedsDisplay(); } -void PictureImageLayer::PaintContents( - SkCanvas* canvas, +scoped_refptr<DisplayItemList> PictureImageLayer::PaintContentsToDisplayList( const gfx::Rect& clip, ContentLayerClient::PaintingControlSetting painting_control) { DCHECK(image_); DCHECK_GT(image_->width(), 0); DCHECK_GT(image_->height(), 0); + // Picture image layers can be used with GatherPixelRefs, so cached SkPictures + // are currently required. + DisplayItemListSettings settings; + settings.use_cached_picture = true; + scoped_refptr<DisplayItemList> display_list = + DisplayItemList::Create(clip, settings); + + SkPictureRecorder recorder; + SkCanvas* canvas = recorder.beginRecording(gfx::RectToSkRect(clip)); + SkScalar content_to_layer_scale_x = SkFloatToScalar(static_cast<float>(bounds().width()) / image_->width()); SkScalar content_to_layer_scale_y = @@ -67,21 +76,6 @@ // to the root canvas, this draw must use the kSrcOver_Mode so that // transparent images blend correctly. canvas->drawImage(image_.get(), 0, 0); -} - -scoped_refptr<DisplayItemList> PictureImageLayer::PaintContentsToDisplayList( - const gfx::Rect& clip, - ContentLayerClient::PaintingControlSetting painting_control) { - // Picture image layers can be used with GatherPixelRefs, so cached SkPictures - // are currently required. - DisplayItemListSettings settings; - settings.use_cached_picture = true; - scoped_refptr<DisplayItemList> display_list = - DisplayItemList::Create(clip, settings); - - SkPictureRecorder recorder; - SkCanvas* canvas = recorder.beginRecording(gfx::RectToSkRect(clip)); - PaintContents(canvas, clip, painting_control); skia::RefPtr<SkPicture> picture = skia::AdoptRef(recorder.endRecordingAsPicture());
diff --git a/cc/layers/picture_image_layer.h b/cc/layers/picture_image_layer.h index df306868..a283c45 100644 --- a/cc/layers/picture_image_layer.h +++ b/cc/layers/picture_image_layer.h
@@ -25,10 +25,6 @@ scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; // ContentLayerClient implementation. - void PaintContents( - SkCanvas* canvas, - const gfx::Rect& clip, - ContentLayerClient::PaintingControlSetting painting_control) override; scoped_refptr<DisplayItemList> PaintContentsToDisplayList( const gfx::Rect& clip, ContentLayerClient::PaintingControlSetting painting_control) override;
diff --git a/cc/layers/picture_layer_unittest.cc b/cc/layers/picture_layer_unittest.cc index 2f5b55f..dffbad4 100644 --- a/cc/layers/picture_layer_unittest.cc +++ b/cc/layers/picture_layer_unittest.cc
@@ -23,9 +23,6 @@ class MockContentLayerClient : public ContentLayerClient { public: - void PaintContents(SkCanvas* canvas, - const gfx::Rect& clip, - PaintingControlSetting picture_control) override {} scoped_refptr<DisplayItemList> PaintContentsToDisplayList( const gfx::Rect& clip, PaintingControlSetting picture_control) override {
diff --git a/cc/surfaces/surface.cc b/cc/surfaces/surface.cc index 16987cb8..e3b0f5ec 100644 --- a/cc/surfaces/surface.cc +++ b/cc/surfaces/surface.cc
@@ -98,11 +98,22 @@ void Surface::RequestCopyOfOutput(scoped_ptr<CopyOutputRequest> copy_request) { if (current_frame_ && - !current_frame_->delegated_frame_data->render_pass_list.empty()) - current_frame_->delegated_frame_data->render_pass_list.back() - ->copy_requests.push_back(copy_request.Pass()); - else + !current_frame_->delegated_frame_data->render_pass_list.empty()) { + ScopedPtrVector<CopyOutputRequest>& copy_requests = + current_frame_->delegated_frame_data->render_pass_list.back() + ->copy_requests; + + if (void* source = copy_request->source()) { + // Remove existing CopyOutputRequests made on the Surface by the same + // source. + auto to_remove = copy_requests.remove_if([source]( + const CopyOutputRequest* x) { return x->source() == source; }); + copy_requests.erase(to_remove, copy_requests.end()); + } + copy_requests.push_back(copy_request.Pass()); + } else { copy_request->SendEmptyResult(); + } } void Surface::TakeCopyOutputRequests(
diff --git a/cc/surfaces/surface_aggregator.cc b/cc/surfaces/surface_aggregator.cc index 69618ba8b..902f836 100644 --- a/cc/surfaces/surface_aggregator.cc +++ b/cc/surfaces/surface_aggregator.cc
@@ -547,9 +547,6 @@ if (provider_) provider_->DeclareUsedResourcesFromChild(child_id, referenced_resources); - for (const auto& render_pass : frame_data->render_pass_list) - has_copy_requests_ |= !render_pass->copy_requests.empty(); - gfx::Rect damage_rect; if (!frame_data->render_pass_list.empty()) { RenderPass* last_pass = frame_data->render_pass_list.back(); @@ -566,6 +563,13 @@ damage_rect.Union( MathUtil::MapEnclosingClippedRect(surface_info.second, surface_damage)); } + + if (surface->factory()) + surface->factory()->WillDrawSurface(surface->surface_id(), damage_rect); + + for (const auto& render_pass : frame_data->render_pass_list) + has_copy_requests_ |= !render_pass->copy_requests.empty(); + referenced_surfaces_.erase(it); return damage_rect; }
diff --git a/cc/surfaces/surface_aggregator_unittest.cc b/cc/surfaces/surface_aggregator_unittest.cc index bfec6e6..bee479c 100644 --- a/cc/surfaces/surface_aggregator_unittest.cc +++ b/cc/surfaces/surface_aggregator_unittest.cc
@@ -43,6 +43,13 @@ class EmptySurfaceFactoryClient : public SurfaceFactoryClient { public: void ReturnResources(const ReturnedResourceArray& resources) override {} + void WillDrawSurface(SurfaceId id, const gfx::Rect& damage_rect) override { + last_surface_id_ = id; + last_damage_rect_ = damage_rect; + } + + gfx::Rect last_damage_rect_; + SurfaceId last_surface_id_; }; class SurfaceAggregatorTest : public testing::Test { @@ -166,6 +173,10 @@ SurfaceId ids[] = {root_surface_id_}; AggregateAndVerify(passes, arraysize(passes), ids, arraysize(ids)); + + // Check that WillDrawSurface was called. + EXPECT_EQ(gfx::Rect(SurfaceSize()), empty_client_.last_damage_rect_); + EXPECT_EQ(root_surface_id_, empty_client_.last_surface_id_); } TEST_F(SurfaceAggregatorValidSurfaceTest, OpacityCopied) {
diff --git a/cc/surfaces/surface_factory.cc b/cc/surfaces/surface_factory.cc index 3e83c8c..72ebdc40d 100644 --- a/cc/surfaces/surface_factory.cc +++ b/cc/surfaces/surface_factory.cc
@@ -8,6 +8,7 @@ #include "cc/output/compositor_frame.h" #include "cc/output/copy_output_request.h" #include "cc/surfaces/surface.h" +#include "cc/surfaces/surface_factory_client.h" #include "cc/surfaces/surface_manager.h" #include "ui/gfx/geometry/size.h" @@ -75,6 +76,11 @@ manager_->SurfaceModified(surface_id); } +void SurfaceFactory::WillDrawSurface(SurfaceId id, + const gfx::Rect& damage_rect) { + client_->WillDrawSurface(id, damage_rect); +} + void SurfaceFactory::ReceiveFromChild( const TransferableResourceArray& resources) { holder_.ReceiveFromChild(resources);
diff --git a/cc/surfaces/surface_factory.h b/cc/surfaces/surface_factory.h index 5af8d2e..762d5a2 100644 --- a/cc/surfaces/surface_factory.h +++ b/cc/surfaces/surface_factory.h
@@ -11,6 +11,7 @@ #include "base/containers/scoped_ptr_hash_map.h" #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" +#include "base/observer_list.h" #include "cc/output/compositor_frame.h" #include "cc/surfaces/surface_id.h" #include "cc/surfaces/surface_resource_holder.h" @@ -55,6 +56,8 @@ void RequestCopyOfSurface(SurfaceId surface_id, scoped_ptr<CopyOutputRequest> copy_request); + void WillDrawSurface(SurfaceId id, const gfx::Rect& damage_rect); + SurfaceFactoryClient* client() { return client_; } void ReceiveFromChild(const TransferableResourceArray& resources);
diff --git a/cc/surfaces/surface_factory_client.h b/cc/surfaces/surface_factory_client.h index 9866b27..c2a04af6 100644 --- a/cc/surfaces/surface_factory_client.h +++ b/cc/surfaces/surface_factory_client.h
@@ -6,7 +6,9 @@ #define CC_SURFACES_SURFACE_FACTORY_CLIENT_H_ #include "cc/resources/returned_resource.h" +#include "cc/surfaces/surface_id.h" #include "cc/surfaces/surfaces_export.h" +#include "ui/gfx/geometry/rect.h" namespace cc { @@ -15,6 +17,9 @@ virtual ~SurfaceFactoryClient() {} virtual void ReturnResources(const ReturnedResourceArray& resources) = 0; + + virtual void WillDrawSurface(SurfaceId surface_id, + const gfx::Rect& damage_rect) {} }; } // namespace cc
diff --git a/cc/surfaces/surface_factory_unittest.cc b/cc/surfaces/surface_factory_unittest.cc index c7ce9640..9629a4e 100644 --- a/cc/surfaces/surface_factory_unittest.cc +++ b/cc/surfaces/surface_factory_unittest.cc
@@ -4,6 +4,8 @@ #include "base/bind.h" #include "cc/output/compositor_frame.h" +#include "cc/output/copy_output_request.h" +#include "cc/output/copy_output_result.h" #include "cc/output/delegated_frame_data.h" #include "cc/resources/resource_provider.h" #include "cc/surfaces/surface.h" @@ -519,5 +521,61 @@ surface_id_ = SurfaceId(); } +void CopyRequestTestCallback(bool* called, + scoped_ptr<CopyOutputResult> result) { + *called = true; +} + +TEST_F(SurfaceFactoryTest, DuplicateCopyRequest) { + { + scoped_ptr<RenderPass> render_pass(RenderPass::Create()); + render_pass->referenced_surfaces.push_back(surface_id_); + scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); + frame_data->render_pass_list.push_back(render_pass.Pass()); + scoped_ptr<CompositorFrame> frame(new CompositorFrame); + frame->delegated_frame_data = frame_data.Pass(); + factory_.SubmitCompositorFrame(surface_id_, frame.Pass(), + SurfaceFactory::DrawCallback()); + } + void* source1 = &source1; + void* source2 = &source2; + + bool called1 = false; + scoped_ptr<CopyOutputRequest> request; + request = CopyOutputRequest::CreateRequest( + base::Bind(&CopyRequestTestCallback, &called1)); + request->set_source(source1); + + factory_.RequestCopyOfSurface(surface_id_, request.Pass()); + EXPECT_FALSE(called1); + + bool called2 = false; + request = CopyOutputRequest::CreateRequest( + base::Bind(&CopyRequestTestCallback, &called2)); + request->set_source(source2); + + factory_.RequestCopyOfSurface(surface_id_, request.Pass()); + // Callbacks have different sources so neither should be called. + EXPECT_FALSE(called1); + EXPECT_FALSE(called2); + + bool called3 = false; + request = CopyOutputRequest::CreateRequest( + base::Bind(&CopyRequestTestCallback, &called3)); + request->set_source(source1); + + factory_.RequestCopyOfSurface(surface_id_, request.Pass()); + // Two callbacks are from source1, so the first should be called. + EXPECT_TRUE(called1); + EXPECT_FALSE(called2); + EXPECT_FALSE(called3); + + factory_.Destroy(surface_id_); + surface_id_ = SurfaceId(); + EXPECT_TRUE(called1); + EXPECT_TRUE(called2); + EXPECT_TRUE(called3); +} + } // namespace } // namespace cc
diff --git a/cc/test/fake_content_layer_client.cc b/cc/test/fake_content_layer_client.cc index eb95c38..bfa7c19 100644 --- a/cc/test/fake_content_layer_client.cc +++ b/cc/test/fake_content_layer_client.cc
@@ -35,39 +35,6 @@ FakeContentLayerClient::~FakeContentLayerClient() { } -void FakeContentLayerClient::PaintContents( - SkCanvas* canvas, - const gfx::Rect& paint_rect, - PaintingControlSetting painting_control) { - last_canvas_ = canvas; - last_painting_control_ = painting_control; - - canvas->clipRect(gfx::RectToSkRect(paint_rect)); - for (RectPaintVector::const_iterator it = draw_rects_.begin(); - it != draw_rects_.end(); ++it) { - const gfx::RectF& draw_rect = it->first; - const SkPaint& paint = it->second; - canvas->drawRect(gfx::RectFToSkRect(draw_rect), paint); - } - - for (ImageVector::const_iterator it = draw_images_.begin(); - it != draw_images_.end(); ++it) { - canvas->drawImage(it->image.get(), it->point.x(), it->point.y(), - &it->paint); - } - - if (fill_with_nonsolid_color_) { - gfx::Rect draw_rect = paint_rect; - bool red = true; - while (!draw_rect.IsEmpty()) { - SkPaint paint; - paint.setColor(red ? SK_ColorRED : SK_ColorBLUE); - canvas->drawIRect(gfx::RectToSkIRect(draw_rect), paint); - draw_rect.Inset(1, 1); - } - } -} - scoped_refptr<DisplayItemList> FakeContentLayerClient::PaintContentsToDisplayList( const gfx::Rect& clip,
diff --git a/cc/test/fake_content_layer_client.h b/cc/test/fake_content_layer_client.h index ead804ab..e24fee7e 100644 --- a/cc/test/fake_content_layer_client.h +++ b/cc/test/fake_content_layer_client.h
@@ -38,9 +38,6 @@ FakeContentLayerClient(); ~FakeContentLayerClient() override; - void PaintContents(SkCanvas* canvas, - const gfx::Rect& rect, - PaintingControlSetting painting_control) override; scoped_refptr<DisplayItemList> PaintContentsToDisplayList( const gfx::Rect& clip, PaintingControlSetting painting_control) override;
diff --git a/cc/test/solid_color_content_layer_client.cc b/cc/test/solid_color_content_layer_client.cc index bf9ac345..ed84bec4 100644 --- a/cc/test/solid_color_content_layer_client.cc +++ b/cc/test/solid_color_content_layer_client.cc
@@ -15,17 +15,6 @@ namespace cc { -// TODO(pdr): Remove PaintContents as all calls should go through -// PaintContentsToDisplayList. -void SolidColorContentLayerClient::PaintContents( - SkCanvas* canvas, - const gfx::Rect& rect, - PaintingControlSetting painting_control) { - scoped_refptr<DisplayItemList> contents = - PaintContentsToDisplayList(rect, painting_control); - contents->Raster(canvas, nullptr, rect, 1.0f); -} - scoped_refptr<DisplayItemList> SolidColorContentLayerClient::PaintContentsToDisplayList( const gfx::Rect& clip,
diff --git a/cc/test/solid_color_content_layer_client.h b/cc/test/solid_color_content_layer_client.h index 5ad35993..c39d567c 100644 --- a/cc/test/solid_color_content_layer_client.h +++ b/cc/test/solid_color_content_layer_client.h
@@ -16,9 +16,6 @@ explicit SolidColorContentLayerClient(SkColor color) : color_(color) {} // ContentLayerClient implementation. - void PaintContents(SkCanvas* canvas, - const gfx::Rect& rect, - PaintingControlSetting painting_control) override; scoped_refptr<DisplayItemList> PaintContentsToDisplayList( const gfx::Rect& clip, PaintingControlSetting painting_control) override;
diff --git a/cc/trees/draw_property_utils.cc b/cc/trees/draw_property_utils.cc index 1554142..5969636 100644 --- a/cc/trees/draw_property_utils.cc +++ b/cc/trees/draw_property_utils.cc
@@ -682,7 +682,7 @@ return gfx::ToEnclosingRect(parent_clip_node->data.clip_in_target_space); } -gfx::Transform SurfaceScreenSpaceTransform( +gfx::Transform SurfaceScreenSpaceTransformFromPropertyTrees( const RenderSurfaceImpl* render_surface, const TransformTree& tree) { const TransformNode* node = tree.Node(render_surface->TransformTreeIndex()); @@ -888,8 +888,9 @@ SurfaceDrawOpacity(render_surface, property_trees->effect_tree); draw_properties->draw_transform = SurfaceDrawTransform(render_surface, property_trees->transform_tree); - draw_properties->screen_space_transform = SurfaceScreenSpaceTransform( - render_surface, property_trees->transform_tree); + draw_properties->screen_space_transform = + SurfaceScreenSpaceTransformFromPropertyTrees( + render_surface, property_trees->transform_tree); if (render_surface->HasReplica()) { gfx::Transform replica_to_surface = ReplicaToSurfaceTransform(
diff --git a/cc/trees/draw_property_utils.h b/cc/trees/draw_property_utils.h index 2200959..858f0fc 100644 --- a/cc/trees/draw_property_utils.h +++ b/cc/trees/draw_property_utils.h
@@ -103,6 +103,10 @@ ScreenSpaceTransformFromPropertyTrees(const LayerImpl* layer, const TransformTree& tree); +gfx::Transform CC_EXPORT SurfaceScreenSpaceTransformFromPropertyTrees( + const RenderSurfaceImpl* render_surface, + const TransformTree& tree); + void CC_EXPORT UpdatePageScaleFactorInPropertyTrees(PropertyTrees* property_trees, const LayerImpl* page_scale_layer,
diff --git a/cc/trees/layer_tree_host_common_unittest.cc b/cc/trees/layer_tree_host_common_unittest.cc index ac77ea4..0bc190c 100644 --- a/cc/trees/layer_tree_host_common_unittest.cc +++ b/cc/trees/layer_tree_host_common_unittest.cc
@@ -60,9 +60,6 @@ public: MockContentLayerClient() {} ~MockContentLayerClient() override {} - void PaintContents(SkCanvas* canvas, - const gfx::Rect& clip, - PaintingControlSetting picture_control) override {} scoped_refptr<DisplayItemList> PaintContentsToDisplayList( const gfx::Rect& clip, PaintingControlSetting picture_control) override {
diff --git a/cc/trees/layer_tree_host_pixeltest_masks.cc b/cc/trees/layer_tree_host_pixeltest_masks.cc index ce9dde5..929d8c0 100644 --- a/cc/trees/layer_tree_host_pixeltest_masks.cc +++ b/cc/trees/layer_tree_host_pixeltest_masks.cc
@@ -32,16 +32,6 @@ bool FillsBoundsCompletely() const override { return false; } size_t GetApproximateUnsharedMemoryUsage() const override { return 0; } - // TODO(pdr): Remove PaintContents as all calls should go through - // PaintContentsToDisplayList. - void PaintContents(SkCanvas* canvas, - const gfx::Rect& rect, - PaintingControlSetting picture_control) override { - scoped_refptr<DisplayItemList> contents = - PaintContentsToDisplayList(rect, picture_control); - contents->Raster(canvas, nullptr, rect, 1.0f); - } - scoped_refptr<DisplayItemList> PaintContentsToDisplayList( const gfx::Rect& clip, PaintingControlSetting picture_control) override { @@ -119,8 +109,10 @@ SkCanvas* canvas = surface->getCanvas(); canvas->scale(SkIntToScalar(4), SkIntToScalar(4)); MaskContentLayerClient client(mask_bounds); - client.PaintContents(canvas, gfx::Rect(mask_bounds), - ContentLayerClient::PAINTING_BEHAVIOR_NORMAL); + scoped_refptr<DisplayItemList> mask_display_list = + client.PaintContentsToDisplayList( + gfx::Rect(mask_bounds), ContentLayerClient::PAINTING_BEHAVIOR_NORMAL); + mask_display_list->Raster(canvas, nullptr, gfx::Rect(mask_bounds), 1.0f); skia::RefPtr<const SkImage> image = skia::AdoptRef(surface->newImageSnapshot()); mask->SetImage(image.Pass()); @@ -319,15 +311,6 @@ ~CheckerContentLayerClient() override {} bool FillsBoundsCompletely() const override { return false; } size_t GetApproximateUnsharedMemoryUsage() const override { return 0; } - // TODO(pdr): Remove PaintContents as all calls should go through - // PaintContentsToDisplayList. - void PaintContents(SkCanvas* canvas, - const gfx::Rect& rect, - PaintingControlSetting picture_control) override { - scoped_refptr<DisplayItemList> contents = - PaintContentsToDisplayList(rect, picture_control); - contents->Raster(canvas, nullptr, rect, 1.0f); - } scoped_refptr<DisplayItemList> PaintContentsToDisplayList( const gfx::Rect& clip, PaintingControlSetting picture_control) override { @@ -375,15 +358,6 @@ ~CircleContentLayerClient() override {} bool FillsBoundsCompletely() const override { return false; } size_t GetApproximateUnsharedMemoryUsage() const override { return 0; } - // TODO(pdr): Remove PaintContents as all calls should go through - // PaintContentsToDisplayList. - void PaintContents(SkCanvas* canvas, - const gfx::Rect& rect, - PaintingControlSetting picture_control) override { - scoped_refptr<DisplayItemList> contents = - PaintContentsToDisplayList(rect, picture_control); - contents->Raster(canvas, nullptr, rect, 1.0f); - } scoped_refptr<DisplayItemList> PaintContentsToDisplayList( const gfx::Rect& clip, PaintingControlSetting picture_control) override {
diff --git a/cc/trees/layer_tree_host_pixeltest_tiles.cc b/cc/trees/layer_tree_host_pixeltest_tiles.cc index f013e98..0d036fb 100644 --- a/cc/trees/layer_tree_host_pixeltest_tiles.cc +++ b/cc/trees/layer_tree_host_pixeltest_tiles.cc
@@ -92,10 +92,6 @@ explicit BlueYellowClient(const gfx::Size& size) : size_(size), blue_top_(true) {} - void PaintContents(SkCanvas* canvas, - const gfx::Rect& clip, - PaintingControlSetting painting_status) override {} - scoped_refptr<DisplayItemList> PaintContentsToDisplayList( const gfx::Rect& clip, PaintingControlSetting painting_status) override {
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc index d3c67d7..e75b3e9 100644 --- a/cc/trees/layer_tree_host_unittest.cc +++ b/cc/trees/layer_tree_host_unittest.cc
@@ -1553,11 +1553,6 @@ void SetTestLayer(Layer* test_layer) { test_layer_ = test_layer; } - void PaintContents(SkCanvas* canvas, - const gfx::Rect& clip, - PaintingControlSetting picture_control) override { - NOTIMPLEMENTED(); - } scoped_refptr<DisplayItemList> PaintContentsToDisplayList( const gfx::Rect& clip, PaintingControlSetting picture_control) override { @@ -2159,12 +2154,6 @@ void set_layer(Layer* layer) { layer_ = layer; } - void PaintContents(SkCanvas* canvas, - const gfx::Rect& clip, - PaintingControlSetting picture_control) override { - NOTIMPLEMENTED(); - } - scoped_refptr<DisplayItemList> PaintContentsToDisplayList( const gfx::Rect& clip, PaintingControlSetting picture_control) override {
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc index dda446a8..a77e517 100644 --- a/cc/trees/layer_tree_impl.cc +++ b/cc/trees/layer_tree_impl.cc
@@ -26,6 +26,7 @@ #include "cc/layers/render_surface_impl.h" #include "cc/layers/scrollbar_layer_impl_base.h" #include "cc/resources/ui_resource_request.h" +#include "cc/trees/draw_property_utils.h" #include "cc/trees/layer_tree_host_common.h" #include "cc/trees/layer_tree_host_impl.h" #include "cc/trees/occlusion_tracker.h" @@ -1375,21 +1376,52 @@ return layer->parent(); } +static const gfx::Transform LayerScreenSpaceTransform( + const LayerImpl* layer, + const TransformTree& transform_tree, + const bool use_property_trees) { + if (!use_property_trees) + return layer->screen_space_transform(); + // When we use property trees, UpdateDrawProperties does not update the draw + // properties of a layer that is not in render surface layer list, so we need + // to compute the screen space transform. + return layer->IsDrawnRenderSurfaceLayerListMember() + ? layer->screen_space_transform() + : ScreenSpaceTransformFromPropertyTrees(layer, transform_tree); +} + +static const gfx::Transform SurfaceScreenSpaceTransform( + const LayerImpl* layer, + const TransformTree& transform_tree, + const bool use_property_trees) { + DCHECK(layer->render_surface()); + if (!use_property_trees) + return layer->render_surface()->screen_space_transform(); + return layer->IsDrawnRenderSurfaceLayerListMember() + ? layer->render_surface()->screen_space_transform() + : SurfaceScreenSpaceTransformFromPropertyTrees( + layer->render_surface(), transform_tree); +} + static bool PointIsClippedBySurfaceOrClipRect( const gfx::PointF& screen_space_point, - const LayerImpl* layer) { + const LayerImpl* layer, + const TransformTree& transform_tree, + const bool use_property_trees) { // Walk up the layer tree and hit-test any render_surfaces and any layer // clip rects that are active. for (; layer; layer = GetNextClippingLayer(layer)) { if (layer->render_surface() && !PointHitsRect(screen_space_point, - layer->render_surface()->screen_space_transform(), - layer->render_surface()->content_rect(), - NULL)) + SurfaceScreenSpaceTransform(layer, transform_tree, + use_property_trees), + layer->render_surface()->content_rect(), NULL)) return true; if (LayerClipsSubtree(layer) && - !PointHitsRect(screen_space_point, layer->screen_space_transform(), + !PointHitsRect(screen_space_point, + LayerScreenSpaceTransform(layer, transform_tree, + use_property_trees), gfx::Rect(layer->bounds()), NULL)) return true; } @@ -1401,18 +1433,21 @@ static bool PointHitsLayer(const LayerImpl* layer, const gfx::PointF& screen_space_point, - float* distance_to_intersection) { + float* distance_to_intersection, + const TransformTree& transform_tree, + const bool use_property_trees) { gfx::Rect content_rect(layer->bounds()); - if (!PointHitsRect(screen_space_point, - layer->screen_space_transform(), - content_rect, - distance_to_intersection)) + if (!PointHitsRect( + screen_space_point, + LayerScreenSpaceTransform(layer, transform_tree, use_property_trees), + content_rect, distance_to_intersection)) return false; // At this point, we think the point does hit the layer, but we need to walk // up the parents to ensure that the layer was not clipped in such a way // that the hit point actually should not hit the layer. - if (PointIsClippedBySurfaceOrClipRect(screen_space_point, layer)) + if (PointIsClippedBySurfaceOrClipRect(screen_space_point, layer, + transform_tree, use_property_trees)) return false; // Skip the HUD layer. @@ -1437,17 +1472,21 @@ const gfx::PointF& screen_space_point, LayerImpl* layer, const Functor& func, + const TransformTree& transform_tree, + const bool use_property_trees, FindClosestMatchingLayerDataForRecursion* data_for_recursion) { size_t children_size = layer->children().size(); for (size_t i = 0; i < children_size; ++i) { size_t index = children_size - 1 - i; FindClosestMatchingLayer(screen_space_point, layer->children()[index], func, + transform_tree, use_property_trees, data_for_recursion); } float distance_to_intersection = 0.f; if (func(layer) && - PointHitsLayer(layer, screen_space_point, &distance_to_intersection) && + PointHitsLayer(layer, screen_space_point, &distance_to_intersection, + transform_tree, use_property_trees) && ((!data_for_recursion->closest_match || distance_to_intersection > data_for_recursion->closest_distance))) { data_for_recursion->closest_distance = distance_to_intersection; @@ -1482,10 +1521,10 @@ LayerImpl* LayerTreeImpl::FindFirstScrollingLayerThatIsHitByPoint( const gfx::PointF& screen_space_point) { FindClosestMatchingLayerDataForRecursion data_for_recursion; - FindClosestMatchingLayer(screen_space_point, - root_layer(), - FindScrollingLayerFunctor(), - &data_for_recursion); + FindClosestMatchingLayer( + screen_space_point, root_layer(), FindScrollingLayerFunctor(), + property_trees_.transform_tree, settings().verify_property_trees, + &data_for_recursion); return data_for_recursion.closest_match; } @@ -1506,19 +1545,24 @@ if (!UpdateDrawProperties(update_lcd_text)) return NULL; FindClosestMatchingLayerDataForRecursion data_for_recursion; - FindClosestMatchingLayer(screen_space_point, - root_layer(), + FindClosestMatchingLayer(screen_space_point, root_layer(), HitTestVisibleScrollableOrTouchableFunctor(), + property_trees_.transform_tree, + settings().verify_property_trees, &data_for_recursion); return data_for_recursion.closest_match; } static bool LayerHasTouchEventHandlersAt(const gfx::PointF& screen_space_point, - LayerImpl* layer_impl) { + LayerImpl* layer_impl, + const TransformTree& transform_tree, + const bool use_property_trees) { if (layer_impl->touch_event_handler_region().IsEmpty()) return false; - if (!PointHitsRegion(screen_space_point, layer_impl->screen_space_transform(), + if (!PointHitsRegion(screen_space_point, + LayerScreenSpaceTransform(layer_impl, transform_tree, + use_property_trees), layer_impl->touch_event_handler_region())) return false; @@ -1526,7 +1570,8 @@ // on the layer, but we need to walk up the parents to ensure that the layer // was not clipped in such a way that the hit point actually should not hit // the layer. - if (PointIsClippedBySurfaceOrClipRect(screen_space_point, layer_impl)) + if (PointIsClippedBySurfaceOrClipRect(screen_space_point, layer_impl, + transform_tree, use_property_trees)) return false; return true; @@ -1547,16 +1592,20 @@ return NULL; FindWheelEventLayerFunctor func; FindClosestMatchingLayerDataForRecursion data_for_recursion; - FindClosestMatchingLayer(screen_space_point, root_layer(), func, - &data_for_recursion); + FindClosestMatchingLayer( + screen_space_point, root_layer(), func, property_trees_.transform_tree, + settings().verify_property_trees, &data_for_recursion); return data_for_recursion.closest_match; } struct FindTouchEventLayerFunctor { bool operator()(LayerImpl* layer) const { - return LayerHasTouchEventHandlersAt(screen_space_point, layer); + return LayerHasTouchEventHandlersAt(screen_space_point, layer, + transform_tree, use_property_trees); } const gfx::PointF screen_space_point; + const TransformTree& transform_tree; + const bool use_property_trees; }; LayerImpl* LayerTreeImpl::FindLayerThatIsHitByPointInTouchHandlerRegion( @@ -1566,10 +1615,13 @@ bool update_lcd_text = false; if (!UpdateDrawProperties(update_lcd_text)) return NULL; - FindTouchEventLayerFunctor func = {screen_space_point}; + FindTouchEventLayerFunctor func = {screen_space_point, + property_trees_.transform_tree, + settings().verify_property_trees}; FindClosestMatchingLayerDataForRecursion data_for_recursion; FindClosestMatchingLayer( - screen_space_point, root_layer(), func, &data_for_recursion); + screen_space_point, root_layer(), func, property_trees_.transform_tree, + settings().verify_property_trees, &data_for_recursion); return data_for_recursion.closest_match; } @@ -1580,7 +1632,9 @@ static ViewportSelectionBound ComputeViewportSelectionBound( const LayerSelectionBound& layer_bound, LayerImpl* layer, - float device_scale_factor) { + float device_scale_factor, + const TransformTree& transform_tree, + const bool use_property_trees) { ViewportSelectionBound viewport_bound; viewport_bound.type = layer_bound.type; @@ -1589,12 +1643,14 @@ gfx::PointF layer_top = layer_bound.edge_top; gfx::PointF layer_bottom = layer_bound.edge_bottom; + gfx::Transform screen_space_transform = + LayerScreenSpaceTransform(layer, transform_tree, use_property_trees); bool clipped = false; gfx::PointF screen_top = - MathUtil::MapPoint(layer->screen_space_transform(), layer_top, &clipped); - gfx::PointF screen_bottom = MathUtil::MapPoint( - layer->screen_space_transform(), layer_bottom, &clipped); + MathUtil::MapPoint(screen_space_transform, layer_top, &clipped); + gfx::PointF screen_bottom = + MathUtil::MapPoint(screen_space_transform, layer_bottom, &clipped); // MapPoint can produce points with NaN components (even when no inputs are // NaN). Since consumers of ViewportSelectionBounds may round |edge_top| or @@ -1618,12 +1674,13 @@ gfx::PointF visibility_point = layer_bottom + visibility_offset; if (visibility_point.x() <= 0) visibility_point.set_x(visibility_point.x() + device_scale_factor); - visibility_point = MathUtil::MapPoint( - layer->screen_space_transform(), visibility_point, &clipped); + visibility_point = + MathUtil::MapPoint(screen_space_transform, visibility_point, &clipped); float intersect_distance = 0.f; viewport_bound.visible = - PointHitsLayer(layer, visibility_point, &intersect_distance); + PointHitsLayer(layer, visibility_point, &intersect_distance, + transform_tree, use_property_trees); return viewport_bound; } @@ -1634,7 +1691,8 @@ selection->start = ComputeViewportSelectionBound( selection_.start, selection_.start.layer_id ? LayerById(selection_.start.layer_id) : NULL, - device_scale_factor()); + device_scale_factor(), property_trees_.transform_tree, + settings().verify_property_trees); selection->is_editable = selection_.is_editable; selection->is_empty_text_form_control = selection_.is_empty_text_form_control; if (selection->start.type == SELECTION_BOUND_CENTER || @@ -1644,7 +1702,8 @@ selection->end = ComputeViewportSelectionBound( selection_.end, selection_.end.layer_id ? LayerById(selection_.end.layer_id) : NULL, - device_scale_factor()); + device_scale_factor(), property_trees_.transform_tree, + settings().verify_property_trees); } }
diff --git a/cc/trees/layer_tree_impl_unittest.cc b/cc/trees/layer_tree_impl_unittest.cc index 182dff1..3c6a453 100644 --- a/cc/trees/layer_tree_impl_unittest.cc +++ b/cc/trees/layer_tree_impl_unittest.cc
@@ -1456,7 +1456,8 @@ EXPECT_EQ(gfx::Rect(test_layer->bounds()), test_layer->visible_layer_rect()); // Hit checking for a point outside the layer should return a null pointer - // (the root layer does not draw content, so it will not be tested either). + // (the root layer does not have a touch event handler, so it will not be + // tested either). gfx::PointF test_point(76.f, 76.f); test_point = gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor); @@ -1711,6 +1712,79 @@ EXPECT_FALSE(result_layer); } +TEST_F(LayerTreeImplTest, HitTestingTouchHandlerRegionsForLayerThatIsNotDrawn) { + scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), 1); + + gfx::Transform identity_matrix; + gfx::Point3F transform_origin; + SetLayerPropertiesForTesting(root.get(), identity_matrix, transform_origin, + gfx::PointF(), gfx::Size(100, 100), true, false, + true); + root->SetDrawsContent(true); + { + Region touch_handler_region(gfx::Rect(10, 10, 30, 30)); + gfx::PointF position; + gfx::Size bounds(50, 50); + scoped_ptr<LayerImpl> test_layer = + LayerImpl::Create(host_impl().active_tree(), 12345); + SetLayerPropertiesForTesting(test_layer.get(), identity_matrix, + transform_origin, position, bounds, true, + false, false); + + test_layer->SetDrawsContent(false); + test_layer->SetTouchEventHandlerRegion(touch_handler_region); + root->AddChild(test_layer.Pass()); + } + host_impl().SetViewportSize(root->bounds()); + host_impl().active_tree()->SetRootLayer(root.Pass()); + host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); + + LayerImpl* test_layer = + host_impl().active_tree()->root_layer()->children()[0]; + // As test_layer doesn't draw content, the layer list of root's render surface + // should contain only the root layer. + ASSERT_EQ(1u, RenderSurfaceLayerList().size()); + ASSERT_EQ(1u, root_layer()->render_surface()->layer_list().size()); + + // Hit testing for a point outside the test layer should return null pointer. + // We also implicitly check that the updated screen space transform of a layer + // that is not in drawn render surface layer list (test_layer) is used during + // hit testing (becuase the point is inside test_layer with respect to the old + // screen space transform). + gfx::PointF test_point(24.f, 24.f); + test_layer->SetPosition(gfx::PointF(25.f, 25.f)); + gfx::Transform expected_screen_space_transform; + expected_screen_space_transform.Translate(25.f, 25.f); + + host_impl().active_tree()->property_trees()->needs_rebuild = true; + host_impl().active_tree()->BuildPropertyTreesForTesting(); + LayerImpl* result_layer = + host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion( + test_point); + EXPECT_FALSE(result_layer); + EXPECT_FALSE(test_layer->IsDrawnRenderSurfaceLayerListMember()); + EXPECT_TRANSFORMATION_MATRIX_EQ(expected_screen_space_transform, + test_layer->screen_space_transform()); + + // We change the position of the test layer such that the test point is now + // inside the test_layer. + test_layer = host_impl().active_tree()->root_layer()->children()[0]; + test_layer->SetPosition(gfx::PointF(10.f, 10.f)); + expected_screen_space_transform.MakeIdentity(); + expected_screen_space_transform.Translate(10.f, 10.f); + + host_impl().active_tree()->property_trees()->needs_rebuild = true; + host_impl().active_tree()->BuildPropertyTreesForTesting(); + result_layer = + host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion( + test_point); + ASSERT_TRUE(result_layer); + ASSERT_EQ(test_layer, result_layer); + EXPECT_FALSE(result_layer->IsDrawnRenderSurfaceLayerListMember()); + EXPECT_TRANSFORMATION_MATRIX_EQ(expected_screen_space_transform, + result_layer->screen_space_transform()); +} + TEST_F(LayerTreeImplTest, SelectionBoundsForSingleLayer) { int root_layer_id = 12345; scoped_ptr<LayerImpl> root =
diff --git a/chrome/android/java/AndroidManifest.xml b/chrome/android/java/AndroidManifest.xml index 02baea8..7525c59 100644 --- a/chrome/android/java/AndroidManifest.xml +++ b/chrome/android/java/AndroidManifest.xml
@@ -403,6 +403,12 @@ android:process=":browser_restart_process"> </activity> + <!-- Activity to list Physical Web Urls --> + <activity android:name="org.chromium.chrome.browser.physicalweb.ListUrlsActivity" + android:label="@string/physical_web_list_urls_activity_title" + android:exported="false"> + </activity> + <!-- Providers for chrome data. --> <provider android:name="org.chromium.chrome.browser.ChromeBrowserProvider" android:authorities="{{ manifest_package }}.ChromeBrowserProvider;{{ manifest_package }}.browser;{{ manifest_package }}"
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelContent.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelContent.java index 5d5a421..8ca7b2e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelContent.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelContent.java
@@ -165,7 +165,6 @@ destroyContentView(); } - System.out.println("ctxs --- OverlayPanelContent.createNewContentView"); mContentViewCore = new ContentViewCore(mActivity); if (mContentViewClient == null) { @@ -227,7 +226,6 @@ */ private void destroyContentView() { if (mContentViewCore != null) { - System.out.println("ctxs --- OverlayPanelContent.destroyContentView"); nativeDestroyWebContents(mNativeOverlayPanelContentPtr); mContentViewCore.getWebContents().destroy(); mContentViewCore.destroy(); @@ -260,7 +258,6 @@ * @param url The URL that should be loaded. */ public void loadUrl(String url) { - System.out.println("ctxs --- OverlayPanelContent.loadUrl"); createNewContentView(); if (mContentViewCore != null && mContentViewCore.getWebContents() != null) { @@ -342,7 +339,6 @@ // your Web History (if enabled). For this reason, onShow() should only be called // when we know for sure the page will be seen by the user. if (mContentViewCore != null) mContentViewCore.onShow(); - if (mContentViewCore != null) System.out.println("ctxs --- mContentViewCore.onShow"); mContentDelegate.onContentViewSeen(); } else {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/ChromeDownloadDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/download/ChromeDownloadDelegate.java index 8c3a49e..2b2cda51 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/ChromeDownloadDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/ChromeDownloadDelegate.java
@@ -29,6 +29,7 @@ import org.chromium.chrome.browser.infobar.ConfirmInfoBar; import org.chromium.chrome.browser.infobar.InfoBar; import org.chromium.chrome.browser.infobar.InfoBarListeners; +import org.chromium.chrome.browser.tab.EmptyTabObserver; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.content.browser.ContentViewDownloadDelegate; @@ -56,14 +57,17 @@ // The application context. private final Context mContext; - private final Tab mTab; + private Tab mTab; private final TabModelSelector mTabModelSelector; // Pending download request for a dangerous file. private DownloadInfo mPendingRequest; + private final EmptyTabObserver mTabObserver; + @Override public void onConfirmInfoBarButtonClicked(ConfirmInfoBar infoBar, boolean confirm) { + assert mTab != null; if (mPendingRequest.hasDownloadId()) { nativeDangerousDownloadValidated(mTab, mPendingRequest.getDownloadId(), confirm); if (confirm) { @@ -115,6 +119,7 @@ public void onInfoBarDismissed(InfoBar infoBar) { if (mPendingRequest != null) { if (mPendingRequest.hasDownloadId()) { + assert mTab != null; nativeDangerousDownloadValidated(mTab, mPendingRequest.getDownloadId(), false); } else if (!mPendingRequest.isGETRequest()) { // Infobar was dismissed, discard the file if a POST download is pending. @@ -135,6 +140,12 @@ Context context, TabModelSelector tabModelSelector, Tab tab) { mContext = context; mTab = tab; + mTabObserver = new EmptyTabObserver() { + @Override + public void onDestroyed(Tab tab) { + mTab = null; + } + }; mTabModelSelector = tabModelSelector; mPendingRequest = null; } @@ -289,6 +300,8 @@ private void confirmDangerousDownload(DownloadInfo downloadInfo) { // A Dangerous file is already pending user confirmation, ignore the new download. if (mPendingRequest != null) return; + // Tab is already destroyed, no need to add an infobar. + if (mTab == null) return; mPendingRequest = downloadInfo; @@ -297,7 +310,6 @@ final String titleText = nativeGetDownloadWarningText(mPendingRequest.getFileName()); final String okButtonText = mContext.getResources().getString(R.string.ok); final String cancelButtonText = mContext.getResources().getString(R.string.cancel); - mTab.getInfoBarContainer().addInfoBar(new ConfirmInfoBar( this, drawableId, null, titleText, null, okButtonText, cancelButtonText)); } @@ -320,6 +332,11 @@ @Override public void requestFileAccess(final long callbackId) { + if (mTab == null) { + // TODO(tedchoc): Show toast (only when activity is alive). + DownloadController.getInstance().onRequestFileAccessResult(callbackId, false); + return; + } final String storagePermission = android.Manifest.permission.WRITE_EXTERNAL_STORAGE; final Activity activity = mTab.getWindowAndroid().getActivity().get(); @@ -431,6 +448,7 @@ } private void launchDownloadInfoBar(DownloadInfo info, String dirName, String fullDirPath) { + if (mTab == null) return; nativeLaunchDownloadOverwriteInfoBar( ChromeDownloadDelegate.this, mTab, info, info.getFileName(), dirName, fullDirPath); } @@ -584,9 +602,13 @@ /** * Close a blank tab just opened for the download purpose. - * @return true iff the tab was closed. + * @return true iff the tab was (already) closed. */ private boolean closeBlankTab() { + if (mTab == null) { + // We do not want caller to dismiss infobar. + return true; + } WebContents contents = mTab.getWebContents(); boolean isInitialNavigation = contents == null || contents.getNavigationController().isInitialNavigation();
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 dd93ae8..26ec9c4 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
@@ -45,8 +45,6 @@ protected static final String TAG = "FirstRunActivity"; // Incoming parameters: - public static final String ORIGINAL_INTENT = "OriginalIntent"; - public static final String FIRE_ORIGINAL_INTENT = "FireOriginalIntent"; public static final String COMING_FROM_CHROME_ICON = "ComingFromChromeIcon"; public static final String USE_FRE_FLOW_SEQUENCER = "UseFreFlowSequencer"; @@ -292,11 +290,6 @@ mFreProperties.putBoolean(RESULT_SHOW_SYNC_SETTINGS, mResultShowSyncSettings); FirstRunFlowSequencer.markFlowAsCompleted(this, mFreProperties); - if (mFreProperties.getBoolean(FirstRunActivity.FIRE_ORIGINAL_INTENT)) { - Intent originalIntent = mFreProperties.getParcelable(FirstRunActivity.ORIGINAL_INTENT); - startActivity(originalIntent); - } - if (DataReductionPromoScreen .getDisplayedDataReductionPromo(getApplicationContext())) { if (DataReductionProxySettings.getInstance().isDataReductionProxyEnabled()) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java index b3353c7..c286e3b4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java
@@ -198,7 +198,7 @@ /** * Checks if the First Run needs to be launched. * @return The intent to launch the First Run Experience if necessary, or null. - * @param activity The context + * @param context The context * @param fromChromeIcon Whether Chrome is opened via the Chrome icon */ public static Intent checkIfFirstRunIsNecessary(Context context, boolean fromChromeIcon) { @@ -224,7 +224,7 @@ /** * @return A generic intent to show the First Run Activity. - * @param context The context + * @param context The context * @param fromChromeIcon Whether Chrome is opened via the Chrome icon */ public static Intent createGenericFirstRunIntent(Context context, boolean fromChromeIcon) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/ListUrlsActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/ListUrlsActivity.java new file mode 100644 index 0000000..5ecbc0ae --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/ListUrlsActivity.java
@@ -0,0 +1,52 @@ +// 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.physicalweb; + +import android.app.ListActivity; +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.view.View; +import android.widget.ArrayAdapter; +import android.widget.ListView; + +/** + * This activity displays a list of nearby URLs as stored in the {@link UrlManager}. + * This activity does not and should not rely directly or indirectly on the native library. + */ +public class ListUrlsActivity extends ListActivity { + private static final String TAG = "PhysicalWeb"; + private ArrayAdapter<String> mAdapter; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + mAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1); + setListAdapter(mAdapter); + } + + @Override + protected void onResume() { + super.onResume(); + mAdapter.clear(); + mAdapter.addAll(UrlManager.getInstance(this).getUrls()); + } + + /** + * Handle a click event. + * @param l The ListView. + * @param v The View that was clicked inside the ListView. + * @param position The position of the clicked element in the list. + * @param id The row id of the clicked element in the list. + */ + @Override + public void onListItemClick(ListView l, View v, int position, long id) { + String url = mAdapter.getItem(position); + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setData(Uri.parse(url)); + startActivity(intent); + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/UrlManager.java b/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/UrlManager.java index 30c093ff..87becc1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/UrlManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/UrlManager.java
@@ -5,7 +5,9 @@ package org.chromium.chrome.browser.physicalweb; import android.app.Notification; +import android.app.PendingIntent; import android.content.Context; +import android.content.Intent; import android.content.SharedPreferences; import android.content.res.Resources; import android.support.v4.app.NotificationCompat; @@ -75,6 +77,13 @@ updateNotification(urls); } + /** + * Get the stored URLs. + */ + public Set<String> getUrls() { + return getCachedUrls(); + } + private Set<String> getCachedUrls() { // Check the version. SharedPreferences prefs = mContext.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE); @@ -98,6 +107,12 @@ editor.apply(); } + private PendingIntent createListUrlsIntent() { + Intent intent = new Intent(mContext, ListUrlsActivity.class); + PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, intent, 0); + return pendingIntent; + } + private void updateNotification(Set<String> urls) { if (urls.isEmpty()) { mNotificationManager.cancel(NotificationConstants.NOTIFICATION_ID_PHYSICAL_WEB); @@ -109,12 +124,14 @@ Resources resources = mContext.getResources(); String title = resources.getQuantityString(R.plurals.physical_web_notification_title, urls.size(), urls.size()); + PendingIntent pendingIntent = createListUrlsIntent(); // Create the notification. Notification notification = new NotificationCompat.Builder(mContext) .setSmallIcon(R.drawable.ic_physical_web_notification) .setContentTitle(title) .setContentText(displayUrl) + .setContentIntent(pendingIntent) .setPriority(NotificationCompat.PRIORITY_MIN) .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) .build();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarControlContainer.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarControlContainer.java index 6c7914c..aa9c2162 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarControlContainer.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarControlContainer.java
@@ -130,6 +130,7 @@ private static class ToolbarViewResourceAdapter extends ViewResourceAdapter { private final int mToolbarActualHeightPx; + private final int mTabStripHeightPx; private final int[] mTempPosition = new int[2]; private final View mToolbarContainer; @@ -147,6 +148,8 @@ } mToolbarActualHeightPx = toolbarContainer.getResources().getDimensionPixelSize( containerHeightResId); + mTabStripHeightPx = toolbarContainer.getResources().getDimensionPixelSize( + R.dimen.tab_strip_height); } /** @@ -186,7 +189,7 @@ @Override protected void computeContentPadding(Rect outContentPadding) { - outContentPadding.set(0, ((View) mToolbar).getTop(), mToolbarContainer.getWidth(), + outContentPadding.set(0, mTabStripHeightPx, mToolbarContainer.getWidth(), mToolbarActualHeightPx); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java index 22bada4a..264d041 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java
@@ -35,7 +35,6 @@ import org.chromium.chrome.browser.util.ColorUtils; import org.chromium.content.browser.ScreenOrientationProvider; import org.chromium.content_public.browser.LoadUrlParams; -import org.chromium.content_public.browser.WebContentsObserver; import org.chromium.net.NetworkChangeNotifier; import org.chromium.ui.base.PageTransition; @@ -55,8 +54,6 @@ private boolean mOldWebappCleanupStarted; - private WebContentsObserver mWebContentsObserver; - private ViewGroup mSplashScreen; private WebappUrlBar mUrlBar; @@ -100,7 +97,6 @@ if (NetworkChangeNotifier.isOnline()) getActivityTab().reloadIgnoringCache(); } - mWebContentsObserver = createWebContentsObserver(); getActivityTab().addObserver(createTabObserver()); getActivityTab().getTabWebContentsDelegateAndroid().setDisplayMode( (int) WebDisplayMode.Standalone); @@ -210,67 +206,6 @@ mUrlBar.update(tab.getUrl(), tab.getSecurityLevel()); } - private WebContentsObserver createWebContentsObserver() { - // TODO: Move to TabObserver eventually. - return new WebContentsObserver(getActivityTab().getWebContents()) { - @Override - public void didNavigateMainFrame(String url, String baseUrl, - boolean isNavigationToDifferentPage, boolean isNavigationInPage, - int statusCode) { - updateUrlBar(); - } - - @Override - public void didAttachInterstitialPage() { - updateUrlBar(); - - int state = ApplicationStatus.getStateForActivity(WebappActivity.this); - if (state == ActivityState.PAUSED || state == ActivityState.STOPPED - || state == ActivityState.DESTROYED) { - return; - } - - // Kick the interstitial navigation to Chrome. - Intent intent = new Intent( - Intent.ACTION_VIEW, Uri.parse(getActivityTab().getUrl())); - intent.setPackage(getPackageName()); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - startActivity(intent); - - // Pretend like the navigation never happened. We delay so that this happens while - // the Activity is in the background. - mHandler.postDelayed(new Runnable() { - @Override - public void run() { - getActivityTab().goBack(); - } - }, MS_BEFORE_NAVIGATING_BACK_FROM_INTERSTITIAL); - } - - @Override - public void didDetachInterstitialPage() { - updateUrlBar(); - } - - @Override - public void didFirstVisuallyNonEmptyPaint() { - if (mSplashScreen == null) return; - - mSplashScreen.animate() - .alpha(0f) - .withEndAction(new Runnable() { - @Override - public void run() { - ViewGroup contentView = - (ViewGroup) findViewById(android.R.id.content); - contentView.removeView(mSplashScreen); - mSplashScreen = null; - } - }); - } - }; - } - private boolean isWebappDomain() { return UrlUtilities.sameDomainOrHost( getActivityTab().getUrl(), getWebappInfo().uri().toString(), true); @@ -308,6 +243,62 @@ if (!isWebappDomain()) return; updateTaskDescription(); } + + @Override + public void onDidNavigateMainFrame(Tab tab, String url, String baseUrl, + boolean isNavigationToDifferentPage, boolean isNavigationInPage, + int statusCode) { + updateUrlBar(); + } + + @Override + public void onDidAttachInterstitialPage(Tab tab) { + updateUrlBar(); + + int state = ApplicationStatus.getStateForActivity(WebappActivity.this); + if (state == ActivityState.PAUSED || state == ActivityState.STOPPED + || state == ActivityState.DESTROYED) { + return; + } + + // Kick the interstitial navigation to Chrome. + Intent intent = new Intent( + Intent.ACTION_VIEW, Uri.parse(getActivityTab().getUrl())); + intent.setPackage(getPackageName()); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(intent); + + // Pretend like the navigation never happened. We delay so that this happens while + // the Activity is in the background. + mHandler.postDelayed(new Runnable() { + @Override + public void run() { + getActivityTab().goBack(); + } + }, MS_BEFORE_NAVIGATING_BACK_FROM_INTERSTITIAL); + } + + @Override + public void onDidDetachInterstitialPage(Tab tab) { + updateUrlBar(); + } + + @Override + public void didFirstVisuallyNonEmptyPaint(Tab tab) { + if (mSplashScreen == null) return; + + mSplashScreen.animate() + .alpha(0f) + .withEndAction(new Runnable() { + @Override + public void run() { + ViewGroup contentView = + (ViewGroup) findViewById(android.R.id.content); + contentView.removeView(mSplashScreen); + mSplashScreen = null; + } + }); + } }; }
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd index 54141b6..2463566 100644 --- a/chrome/android/java/strings/android_chrome_strings.grd +++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -2277,6 +2277,9 @@ </message> <!-- Physical Web strings --> + <message name="IDS_PHYSICAL_WEB_LIST_URLS_ACTIVITY_TITLE" desc="The title for a dialog that shows a list of URLs broadcasted from nearby devices."> + Nearby URLs + </message> <message name="IDS_PHYSICAL_WEB_NOTIFICATION_TITLE" desc="Description of quantity of discovered URLs nearby."> {NUM_URLS, plural, =1 {1 URL nearby}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java index b6e145e..5a6dbe6 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java
@@ -792,6 +792,7 @@ * Tests a sequence in landscape orientation: swiping the overlay open, after an * initial tap that activates the peeking card. */ + @DisabledTest // https://crbug.com/543733 @SmallTest @Feature({"ContextualSearch"}) @Restriction({RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE})
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index e4478cc8..08593186 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -110,6 +110,7 @@ "//components/content_settings/content/common", "//components/content_settings/core/browser", "//components/content_settings/core/common", + "//components/cookie_config", "//components/crx_file", "//components/data_reduction_proxy/core/browser", "//components/data_usage/core",
diff --git a/chrome/browser/chromeos/login/chrome_restart_request.cc b/chrome/browser/chromeos/login/chrome_restart_request.cc index 1cd1713d..9fd082e 100644 --- a/chrome/browser/chromeos/login/chrome_restart_request.cc +++ b/chrome/browser/chromeos/login/chrome_restart_request.cc
@@ -146,6 +146,7 @@ #if defined(ENABLE_TOPCHROME_MD) ::switches::kTopChromeMD, #endif + ::switches::kUIDisablePartialSwap, ::switches::kUIEnableCompositorAnimationTimelines, ::switches::kUIPrioritizeInGpuProcess, #if defined(USE_CRAS) @@ -185,6 +186,7 @@ // Please keep these in alphabetical order. Non-UI Compositor switches // here should also be added to // content/browser/renderer_host/render_process_host_impl.cc. + cc::switches::kDisableCachedPictureRaster, cc::switches::kDisableCompositedAntialiasing, cc::switches::kDisableMainFrameBeforeActivation, cc::switches::kDisableThreadedAnimation, @@ -200,7 +202,6 @@ cc::switches::kShowScreenSpaceRects, cc::switches::kShowSurfaceDamageRects, cc::switches::kSlowDownRasterScaleFactor, - cc::switches::kUIDisablePartialSwap, chromeos::switches::kConsumerDeviceManagementUrl, chromeos::switches::kDbusStub, chromeos::switches::kDbusUnstubClients,
diff --git a/chrome/browser/extensions/chrome_extensions_browser_client.cc b/chrome/browser/extensions/chrome_extensions_browser_client.cc index db81dee..abae1f8 100644 --- a/chrome/browser/extensions/chrome_extensions_browser_client.cc +++ b/chrome/browser/extensions/chrome_extensions_browser_client.cc
@@ -26,6 +26,7 @@ #include "chrome/browser/extensions/extension_system_factory.h" #include "chrome/browser/extensions/extension_util.h" #include "chrome/browser/extensions/menu_manager.h" +#include "chrome/browser/extensions/updater/chrome_update_client_config.h" #include "chrome/browser/external_protocol/external_protocol_handler.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" @@ -36,6 +37,7 @@ #include "chrome/common/extensions/features/feature_channel.h" #include "chrome/common/pref_names.h" #include "components/net_log/chrome_net_log.h" +#include "components/update_client/update_client.h" #include "components/version_info/version_info.h" #include "content/public/browser/render_process_host.h" #include "content/public/common/content_switches.h" @@ -380,4 +382,11 @@ } } +scoped_refptr<update_client::UpdateClient> +ChromeExtensionsBrowserClient::CreateUpdateClient( + content::BrowserContext* context) { + return update_client::UpdateClientFactory( + make_scoped_refptr(new ChromeUpdateClientConfig(context))); +} + } // namespace extensions
diff --git a/chrome/browser/extensions/chrome_extensions_browser_client.h b/chrome/browser/extensions/chrome_extensions_browser_client.h index c9d41a34..4633436 100644 --- a/chrome/browser/extensions/chrome_extensions_browser_client.h +++ b/chrome/browser/extensions/chrome_extensions_browser_client.h
@@ -5,11 +5,13 @@ #ifndef CHROME_BROWSER_EXTENSIONS_CHROME_EXTENSIONS_BROWSER_CLIENT_H_ #define CHROME_BROWSER_EXTENSIONS_CHROME_EXTENSIONS_BROWSER_CLIENT_H_ -#include <map> +#include <string> +#include <vector> #include "base/basictypes.h" #include "base/compiler_specific.h" #include "base/lazy_instance.h" +#include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "chrome/browser/extensions/chrome_notification_observer.h" #include "extensions/browser/extensions_browser_client.h" @@ -111,6 +113,8 @@ int view_instance_id) override; void AttachExtensionTaskManagerTag(content::WebContents* web_contents, ViewType view_type) override; + scoped_refptr<update_client::UpdateClient> CreateUpdateClient( + content::BrowserContext* context) override; private: friend struct base::DefaultLazyInstanceTraits<ChromeExtensionsBrowserClient>;
diff --git a/chrome/browser/extensions/extension_system_impl.cc b/chrome/browser/extensions/extension_system_impl.cc index bbf1452..836c829 100644 --- a/chrome/browser/extensions/extension_system_impl.cc +++ b/chrome/browser/extensions/extension_system_impl.cc
@@ -8,6 +8,7 @@ #include "base/bind.h" #include "base/command_line.h" #include "base/files/file_path.h" +#include "base/files/file_util.h" #include "base/memory/weak_ptr.h" #include "base/strings/string_tokenizer.h" #include "base/trace_event/trace_event.h" @@ -374,6 +375,12 @@ extension); } +void ExtensionSystemImpl::InstallUpdate(const std::string& extension_id, + const base::FilePath& temp_dir) { + NOTREACHED() << "Not yet implemented"; + base::DeleteFile(temp_dir, true /* recursive */); +} + void ExtensionSystemImpl::RegisterExtensionWithRequestContexts( const Extension* extension, const base::Closure& callback) {
diff --git a/chrome/browser/extensions/extension_system_impl.h b/chrome/browser/extensions/extension_system_impl.h index 49369ff8..0ad93570 100644 --- a/chrome/browser/extensions/extension_system_impl.h +++ b/chrome/browser/extensions/extension_system_impl.h
@@ -54,6 +54,8 @@ ContentVerifier* content_verifier() override; // shared scoped_ptr<ExtensionSet> GetDependentExtensions( const Extension* extension) override; + void InstallUpdate(const std::string& extension_id, + const base::FilePath& temp_dir) override; private: friend class ExtensionSystemSharedFactory;
diff --git a/chrome/browser/extensions/test_extension_system.cc b/chrome/browser/extensions/test_extension_system.cc index ad06d0c..5801ae7d 100644 --- a/chrome/browser/extensions/test_extension_system.cc +++ b/chrome/browser/extensions/test_extension_system.cc
@@ -127,6 +127,11 @@ extension); } +void TestExtensionSystem::InstallUpdate(const std::string& extension_id, + const base::FilePath& temp_dir) { + NOTREACHED(); +} + // static scoped_ptr<KeyedService> TestExtensionSystem::Build( content::BrowserContext* profile) {
diff --git a/chrome/browser/extensions/test_extension_system.h b/chrome/browser/extensions/test_extension_system.h index d0c11e4a..9e85ec4 100644 --- a/chrome/browser/extensions/test_extension_system.h +++ b/chrome/browser/extensions/test_extension_system.h
@@ -58,6 +58,8 @@ ContentVerifier* content_verifier() override; scoped_ptr<ExtensionSet> GetDependentExtensions( const Extension* extension) override; + void InstallUpdate(const std::string& extension_id, + const base::FilePath& temp_dir) override; // Note that you probably want to use base::RunLoop().RunUntilIdle() right // after this to run all the accumulated tasks.
diff --git a/chrome/browser/extensions/updater/chrome_update_client_config.cc b/chrome/browser/extensions/updater/chrome_update_client_config.cc new file mode 100644 index 0000000..1c095f7d --- /dev/null +++ b/chrome/browser/extensions/updater/chrome_update_client_config.cc
@@ -0,0 +1,89 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/command_line.h" +#include "base/version.h" +#include "chrome/browser/component_updater/component_patcher_operation_out_of_process.h" +#include "chrome/browser/extensions/updater/chrome_update_client_config.h" +#include "chrome/browser/update_client/chrome_update_query_params_delegate.h" +#include "chrome/common/channel_info.h" +#include "content/public/browser/browser_context.h" + +namespace extensions { + +ChromeUpdateClientConfig::ChromeUpdateClientConfig( + content::BrowserContext* context) + : impl_(base::CommandLine::ForCurrentProcess(), + context->GetRequestContext()) { + impl_.set_enable_alt_source_url(false); +} + +int ChromeUpdateClientConfig::InitialDelay() const { + return impl_.InitialDelay(); +} + +int ChromeUpdateClientConfig::NextCheckDelay() const { + return impl_.NextCheckDelay(); +} + +int ChromeUpdateClientConfig::StepDelay() const { + return impl_.StepDelay(); +} + +int ChromeUpdateClientConfig::OnDemandDelay() const { + return impl_.OnDemandDelay(); +} + +int ChromeUpdateClientConfig::UpdateDelay() const { + return 0; +} + +std::vector<GURL> ChromeUpdateClientConfig::UpdateUrl() const { + return impl_.UpdateUrl(); +} + +std::vector<GURL> ChromeUpdateClientConfig::PingUrl() const { + return impl_.PingUrl(); +} + +base::Version ChromeUpdateClientConfig::GetBrowserVersion() const { + return impl_.GetBrowserVersion(); +} + +std::string ChromeUpdateClientConfig::GetChannel() const { + return chrome::GetChannelString(); +} + +std::string ChromeUpdateClientConfig::GetLang() const { + return ChromeUpdateQueryParamsDelegate::GetLang(); +} + +std::string ChromeUpdateClientConfig::GetOSLongName() const { + return impl_.GetOSLongName(); +} + +std::string ChromeUpdateClientConfig::ExtraRequestParams() const { + return impl_.ExtraRequestParams(); +} + +net::URLRequestContextGetter* ChromeUpdateClientConfig::RequestContext() const { + return impl_.RequestContext(); +} + +scoped_refptr<update_client::OutOfProcessPatcher> +ChromeUpdateClientConfig::CreateOutOfProcessPatcher() const { + return make_scoped_refptr(new component_updater::ChromeOutOfProcessPatcher); +} + +bool ChromeUpdateClientConfig::DeltasEnabled() const { + return impl_.DeltasEnabled(); +} + +bool ChromeUpdateClientConfig::UseBackgroundDownloader() const { + return impl_.UseBackgroundDownloader(); +} + +ChromeUpdateClientConfig::~ChromeUpdateClientConfig() {} + +} // namespace extensions
diff --git a/chrome/browser/extensions/updater/chrome_update_client_config.h b/chrome/browser/extensions/updater/chrome_update_client_config.h new file mode 100644 index 0000000..1e6cab6 --- /dev/null +++ b/chrome/browser/extensions/updater/chrome_update_client_config.h
@@ -0,0 +1,55 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_EXTENSIONS_UPDATER_CHROME_UPDATE_CLIENT_CONFIG_H_ +#define CHROME_BROWSER_EXTENSIONS_UPDATER_CHROME_UPDATE_CLIENT_CONFIG_H_ + +#include <string> +#include <vector> + +#include "base/memory/ref_counted.h" +#include "components/component_updater/configurator_impl.h" +#include "extensions/browser/updater/update_client_config.h" + +namespace content { +class BrowserContext; +} + +namespace extensions { + +class ChromeUpdateClientConfig : public UpdateClientConfig { + public: + explicit ChromeUpdateClientConfig(content::BrowserContext* context); + + int InitialDelay() const override; + int NextCheckDelay() const override; + int StepDelay() const override; + int OnDemandDelay() const override; + int UpdateDelay() const override; + std::vector<GURL> UpdateUrl() const override; + std::vector<GURL> PingUrl() const override; + base::Version GetBrowserVersion() const override; + std::string GetChannel() const override; + std::string GetLang() const override; + std::string GetOSLongName() const override; + std::string ExtraRequestParams() const override; + net::URLRequestContextGetter* RequestContext() const override; + scoped_refptr<update_client::OutOfProcessPatcher> CreateOutOfProcessPatcher() + const override; + bool DeltasEnabled() const override; + bool UseBackgroundDownloader() const override; + + protected: + friend class base::RefCountedThreadSafe<ChromeUpdateClientConfig>; + ~ChromeUpdateClientConfig() override; + + private: + component_updater::ConfiguratorImpl impl_; + + DISALLOW_COPY_AND_ASSIGN(ChromeUpdateClientConfig); +}; + +} // namespace extensions + +#endif // CHROME_BROWSER_EXTENSIONS_UPDATER_CHROME_UPDATE_CLIENT_CONFIG_H_
diff --git a/chrome/browser/google/google_update_win.cc b/chrome/browser/google/google_update_win.cc index 7980192..97d354a 100644 --- a/chrome/browser/google/google_update_win.cc +++ b/chrome/browser/google/google_update_win.cc
@@ -7,6 +7,8 @@ #include <atlbase.h> #include <atlcom.h> +#include <vector> + #include "base/bind.h" #include "base/callback.h" #include "base/files/file_path.h" @@ -206,8 +208,7 @@ gfx::AcceleratedWidget elevation_window, const base::WeakPtr<UpdateCheckDelegate>& delegate); - // Invokes a completion or error method on the caller's delegate, as - // appropriate. + // Invokes a completion or error method on all delegates, as appropriate. ~UpdateCheckDriver(); // Starts an update check. @@ -221,7 +222,7 @@ // |hresult|, installer_exit_code_ to |installer_exit_code|, and // html_error_message_ to a composition of all values suitable for display // to the user. This call should be followed by deletion of the driver, - // which will result in the caller being notified via its delegate. + // which will result in callers being notified via their delegates. void OnUpgradeError(GoogleUpdateErrorCode error_code, HRESULT hresult, int installer_exit_code, @@ -283,10 +284,17 @@ // previous notification) and another future poll will be scheduled. void PollGoogleUpdate(); + // If an UpdateCheckDriver is already running, the delegate is added to the + // existing one instead of creating a new one. + void AddDelegate(const base::WeakPtr<UpdateCheckDelegate>& delegate); + + static UpdateCheckDriver* driver_; + // The task runner on which the update checks runs. scoped_refptr<base::SingleThreadTaskRunner> task_runner_; - // The caller's task runner, on which methods of |delegate_| will be invoked. + // The caller's task runner, on which methods of the |delegates_| will be + // invoked. scoped_refptr<base::SingleThreadTaskRunner> result_runner_; // The UI locale. @@ -298,8 +306,8 @@ // A parent window in case any UX is required (e.g., an elevation prompt). gfx::AcceleratedWidget elevation_window_; - // The caller's delegate by which feedback is conveyed. - base::WeakPtr<UpdateCheckDelegate> delegate_; + // Contains all delegates by which feedback is conveyed. + std::vector<base::WeakPtr<UpdateCheckDelegate>> delegates_; // Number of remaining retries allowed when errors occur. int allowed_retries_; @@ -331,6 +339,8 @@ DISALLOW_COPY_AND_ASSIGN(UpdateCheckDriver); }; +UpdateCheckDriver* UpdateCheckDriver::driver_ = nullptr; + // static void UpdateCheckDriver::RunUpdateCheck( const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, @@ -338,14 +348,21 @@ bool install_update_if_possible, gfx::AcceleratedWidget elevation_window, const base::WeakPtr<UpdateCheckDelegate>& delegate) { - // The driver is owned by itself, and will self-destruct when its work is - // done. - UpdateCheckDriver* driver = - new UpdateCheckDriver(task_runner, locale, install_update_if_possible, - elevation_window, delegate); - task_runner->PostTask(FROM_HERE, - base::Bind(&UpdateCheckDriver::BeginUpdateCheck, - base::Unretained(driver))); + // Create the driver if it doesn't exist, or add the delegate to the existing + // one. + if (!driver_) { + // The driver is owned by itself, and will self-destruct when its work is + // done. + driver_ = + new UpdateCheckDriver(task_runner, locale, install_update_if_possible, + elevation_window, delegate); + task_runner->PostTask(FROM_HERE, + base::Bind(&UpdateCheckDriver::BeginUpdateCheck, + base::Unretained(driver_))); + } else { + DCHECK_EQ(driver_->task_runner_, task_runner); + driver_->AddDelegate(delegate); + } } // Runs on the caller's thread. @@ -360,7 +377,6 @@ locale_(locale), install_update_if_possible_(install_update_if_possible), elevation_window_(elevation_window), - delegate_(delegate), allowed_retries_(kGoogleAllowedRetries), system_level_install_(false), last_reported_progress_(0), @@ -368,6 +384,7 @@ error_code_(GOOGLE_UPDATE_NO_ERROR), hresult_(S_OK), installer_exit_code_(-1) { + delegates_.push_back(delegate); } UpdateCheckDriver::~UpdateCheckDriver() { @@ -386,14 +403,18 @@ installer_exit_code_); } } - if (delegate_) { - if (status_ == UPGRADE_ERROR) - delegate_->OnError(error_code_, html_error_message_, new_version_); - else if (install_update_if_possible_) - delegate_->OnUpgradeComplete(new_version_); - else - delegate_->OnUpdateCheckComplete(new_version_); + for (const auto& delegate : delegates_) { + if (delegate) { + if (status_ == UPGRADE_ERROR) + delegate->OnError(error_code_, html_error_message_, new_version_); + else if (install_update_if_possible_) + delegate->OnUpgradeComplete(new_version_); + else + delegate->OnUpdateCheckComplete(new_version_); + } } + + driver_ = nullptr; } void UpdateCheckDriver::BeginUpdateCheck() { @@ -710,10 +731,12 @@ // It is safe to post this task with an unretained pointer since the task // is guaranteed to run before a subsequent DeleteSoon is handled. - result_runner_->PostTask( - FROM_HERE, - base::Bind(&UpdateCheckDelegate::OnUpgradeProgress, delegate_, - last_reported_progress_, new_version_)); + for (const auto& delegate : delegates_) { + result_runner_->PostTask( + FROM_HERE, + base::Bind(&UpdateCheckDelegate::OnUpgradeProgress, delegate, + last_reported_progress_, new_version_)); + } } // Schedule the next check. @@ -735,6 +758,11 @@ result_runner_->DeleteSoon(FROM_HERE, this); } +void UpdateCheckDriver::AddDelegate( + const base::WeakPtr<UpdateCheckDelegate>& delegate) { + delegates_.push_back(delegate); +} + void UpdateCheckDriver::OnUpgradeError(GoogleUpdateErrorCode error_code, HRESULT hresult, int installer_exit_code,
diff --git a/chrome/browser/google/google_update_win_unittest.cc b/chrome/browser/google/google_update_win_unittest.cc index d7d89629..700c10c 100644 --- a/chrome/browser/google/google_update_win_unittest.cc +++ b/chrome/browser/google/google_update_win_unittest.cc
@@ -952,6 +952,68 @@ task_runner_->RunUntilIdle(); } +TEST_P(GoogleUpdateWinTest, UpdateInstalledMultipleDelegates) { + CComObject<MockAppBundle>* mock_app_bundle = nullptr; + CComObject<MockApp>* mock_app = nullptr; + MakeGoogleUpdateMocks(&mock_app_bundle, &mock_app); + + // Expect the bundle to be called on to start the update. + EXPECT_CALL(*mock_app_bundle, checkForUpdate()).WillOnce(Return(S_OK)); + // Expect the bundle to be called on to start the install. + EXPECT_CALL(*mock_app_bundle, install()).WillOnce(Return(S_OK)); + + mock_app->PushState(STATE_INIT); + mock_app->PushState(STATE_CHECKING_FOR_UPDATE); + mock_app->PushUpdateAvailableState(new_version_); + mock_app->PushState(STATE_WAITING_TO_DOWNLOAD); + mock_app->PushProgressiveState(STATE_DOWNLOADING, 0); + mock_app->PushProgressiveState(STATE_DOWNLOADING, 25); + mock_app->PushProgressiveState(STATE_DOWNLOADING, 25); + mock_app->PushProgressiveState(STATE_DOWNLOADING, 75); + mock_app->PushState(STATE_WAITING_TO_INSTALL); + mock_app->PushProgressiveState(STATE_INSTALLING, 50); + mock_app->PushState(STATE_INSTALL_COMPLETE); + + StrictMock<MockUpdateCheckDelegate> mock_update_check_delegate_2; + { + InSequence callback_sequence; + EXPECT_CALL(mock_update_check_delegate_, + OnUpgradeProgress(0, StrEq(new_version_))); + EXPECT_CALL(mock_update_check_delegate_2, + OnUpgradeProgress(0, StrEq(new_version_))); + + EXPECT_CALL(mock_update_check_delegate_, + OnUpgradeProgress(12, StrEq(new_version_))); + EXPECT_CALL(mock_update_check_delegate_2, + OnUpgradeProgress(12, StrEq(new_version_))); + + EXPECT_CALL(mock_update_check_delegate_, + OnUpgradeProgress(37, StrEq(new_version_))); + EXPECT_CALL(mock_update_check_delegate_2, + OnUpgradeProgress(37, StrEq(new_version_))); + + EXPECT_CALL(mock_update_check_delegate_, + OnUpgradeProgress(50, StrEq(new_version_))); + EXPECT_CALL(mock_update_check_delegate_2, + OnUpgradeProgress(50, StrEq(new_version_))); + + EXPECT_CALL(mock_update_check_delegate_, + OnUpgradeProgress(75, StrEq(new_version_))); + EXPECT_CALL(mock_update_check_delegate_2, + OnUpgradeProgress(75, StrEq(new_version_))); + + EXPECT_CALL(mock_update_check_delegate_, + OnUpgradeComplete(StrEq(new_version_))); + EXPECT_CALL(mock_update_check_delegate_2, + OnUpgradeComplete(StrEq(new_version_))); + } + BeginUpdateCheck(task_runner_, std::string(), true, 0, + mock_update_check_delegate_.AsWeakPtr()); + BeginUpdateCheck(task_runner_, std::string(), true, 0, + mock_update_check_delegate_2.AsWeakPtr()); + task_runner_->RunUntilIdle(); +} + INSTANTIATE_TEST_CASE_P(UserLevel, GoogleUpdateWinTest, Values(false)); INSTANTIATE_TEST_CASE_P(SystemLevel, GoogleUpdateWinTest, Values(true));
diff --git a/chrome/browser/metrics/chrome_metrics_service_client.cc b/chrome/browser/metrics/chrome_metrics_service_client.cc index 244f62f9..433978a0 100644 --- a/chrome/browser/metrics/chrome_metrics_service_client.cc +++ b/chrome/browser/metrics/chrome_metrics_service_client.cc
@@ -28,7 +28,6 @@ #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/crash_keys.h" -#include "chrome/common/pref_names.h" #include "components/metrics/call_stack_profile_metrics_provider.h" #include "components/metrics/drive_metrics_provider.h" #include "components/metrics/gpu/gpu_metrics_provider.h" @@ -168,9 +167,6 @@ // static void ChromeMetricsServiceClient::RegisterPrefs(PrefRegistrySimple* registry) { - registry->RegisterInt64Pref(prefs::kUninstallLastLaunchTimeSec, 0); - registry->RegisterInt64Pref(prefs::kUninstallLastObservedRunTimeSec, 0); - metrics::MetricsService::RegisterPrefs(registry); metrics::StabilityMetricsHelper::RegisterPrefs(registry);
diff --git a/chrome/browser/net/cookie_store_util.h b/chrome/browser/net/cookie_store_util.h deleted file mode 100644 index c05391b..0000000 --- a/chrome/browser/net/cookie_store_util.h +++ /dev/null
@@ -1,27 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_NET_COOKIE_STORE_UTIL_H_ -#define CHROME_BROWSER_NET_COOKIE_STORE_UTIL_H_ - -#include "base/memory/ref_counted.h" -#include "content/public/browser/browser_context.h" -#include "content/public/browser/cookie_store_factory.h" - -class Profile; - -namespace net { -class CookieMonsterDelegate; -} // namespace net - -namespace chrome_browser_net { - -// Factory method for returning a CookieCryptoDelegate if one is appropriate for -// this platform. The object returned is a LazyInstance. Ownership is not -// transferred. -net::CookieCryptoDelegate* GetCookieCryptoDelegate(); - -} // namespace chrome_browser_net - -#endif // CHROME_BROWSER_NET_COOKIE_STORE_UTIL_H_
diff --git a/chrome/browser/net/net_error_tab_helper.cc b/chrome/browser/net/net_error_tab_helper.cc index f0cbcf9..8e325f9b 100644 --- a/chrome/browser/net/net_error_tab_helper.cc +++ b/chrome/browser/net/net_error_tab_helper.cc
@@ -18,14 +18,12 @@ #include "components/error_page/common/net_error_info.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/render_frame_host.h" -#include "content/public/browser/render_view_host.h" #include "ipc/ipc_message_macros.h" #include "net/base/net_errors.h" #include "url/gurl.h" using content::BrowserContext; using content::BrowserThread; -using content::RenderViewHost; using content::WebContents; using content::WebContentsObserver; using error_page::DnsProbeStatus; @@ -82,13 +80,16 @@ testing_state_ = state; } -void NetErrorTabHelper::RenderViewCreated( - content::RenderViewHost* render_view_host) { - content::RenderFrameHost* render_frame_host = - render_view_host->GetMainFrame(); - render_frame_host->Send(new ChromeViewMsg_SetCanShowNetworkDiagnosticsDialog( - render_frame_host->GetRoutingID(), - CanShowNetworkDiagnosticsDialog())); +void NetErrorTabHelper::RenderFrameCreated( + content::RenderFrameHost* render_frame_host) { + // Ignore subframe creation - only main frame error pages can link to the + // platform's network diagnostics dialog. + if (render_frame_host->GetParent()) + return; + render_frame_host->Send( + new ChromeViewMsg_SetCanShowNetworkDiagnosticsDialog( + render_frame_host->GetRoutingID(), + CanShowNetworkDiagnosticsDialog())); } void NetErrorTabHelper::DidStartNavigationToPendingEntry(
diff --git a/chrome/browser/net/net_error_tab_helper.h b/chrome/browser/net/net_error_tab_helper.h index 490b432..4e6b83e 100644 --- a/chrome/browser/net/net_error_tab_helper.h +++ b/chrome/browser/net/net_error_tab_helper.h
@@ -48,7 +48,7 @@ } // content::WebContentsObserver implementation. - void RenderViewCreated(content::RenderViewHost* render_view_host) override; + void RenderFrameCreated(content::RenderFrameHost* render_frame_host) override; void DidStartNavigationToPendingEntry( const GURL& url,
diff --git a/chrome/browser/profiles/DEPS b/chrome/browser/profiles/DEPS index 3e4fe84..b6f5425f 100644 --- a/chrome/browser/profiles/DEPS +++ b/chrome/browser/profiles/DEPS
@@ -1,4 +1,5 @@ include_rules = [ "+components/about_handler", + "+components/cookie_config", "+components/user_manager", ]
diff --git a/chrome/browser/profiles/profile_impl_io_data.cc b/chrome/browser/profiles/profile_impl_io_data.cc index 0ad1af73..e0ca85f1 100644 --- a/chrome/browser/profiles/profile_impl_io_data.cc +++ b/chrome/browser/profiles/profile_impl_io_data.cc
@@ -29,7 +29,6 @@ #include "chrome/browser/io_thread.h" #include "chrome/browser/net/chrome_network_delegate.h" #include "chrome/browser/net/connect_interceptor.h" -#include "chrome/browser/net/cookie_store_util.h" #include "chrome/browser/net/http_server_properties_manager_factory.h" #include "chrome/browser/net/predictor.h" #include "chrome/browser/net/quota_policy_channel_id_store.h" @@ -41,6 +40,7 @@ #include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" +#include "components/cookie_config/cookie_store_util.h" #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h" #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h" #include "components/data_reduction_proxy/core/browser/data_store_impl.h" @@ -513,8 +513,7 @@ lazy_params_->session_cookie_mode, lazy_params_->special_storage_policy.get(), profile_params->cookie_monster_delegate.get()); - cookie_config.crypto_delegate = - chrome_browser_net::GetCookieCryptoDelegate(); + cookie_config.crypto_delegate = cookie_config::GetCookieCryptoDelegate(); cookie_store = content::CreateCookieStore(cookie_config); } @@ -616,8 +615,7 @@ lazy_params_->extensions_cookie_path, lazy_params_->session_cookie_mode, NULL, NULL); - cookie_config.crypto_delegate = - chrome_browser_net::GetCookieCryptoDelegate(); + cookie_config.crypto_delegate = cookie_config::GetCookieCryptoDelegate(); net::CookieStore* extensions_cookie_store = content::CreateCookieStore(cookie_config); // Enable cookies for chrome-extension URLs. @@ -694,8 +692,7 @@ cookie_path, content::CookieStoreConfig::EPHEMERAL_SESSION_COOKIES, NULL, NULL); - cookie_config.crypto_delegate = - chrome_browser_net::GetCookieCryptoDelegate(); + cookie_config.crypto_delegate = cookie_config::GetCookieCryptoDelegate(); cookie_store = content::CreateCookieStore(cookie_config); }
diff --git a/chrome/browser/profiles/profile_io_data.cc b/chrome/browser/profiles/profile_io_data.cc index 52d9bc1..b43f827f 100644 --- a/chrome/browser/profiles/profile_io_data.cc +++ b/chrome/browser/profiles/profile_io_data.cc
@@ -37,7 +37,6 @@ #include "chrome/browser/net/chrome_http_user_agent_settings.h" #include "chrome/browser/net/chrome_network_delegate.h" #include "chrome/browser/net/chrome_url_request_context_getter.h" -#include "chrome/browser/net/cookie_store_util.h" #include "chrome/browser/net/proxy_service_factory.h" #include "chrome/browser/net/resource_prefetch_predictor_observer.h" #include "chrome/browser/predictors/resource_prefetch_predictor.h" @@ -54,6 +53,7 @@ #include "components/content_settings/core/browser/content_settings_provider.h" #include "components/content_settings/core/browser/cookie_settings.h" #include "components/content_settings/core/browser/host_content_settings_map.h" +#include "components/cookie_config/cookie_store_util.h" #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h" #include "components/dom_distiller/core/url_constants.h" #include "components/metrics/metrics_pref_names.h"
diff --git a/chrome/browser/resources/chromeos/chromevox/chromevox.gni b/chrome/browser/resources/chromeos/chromevox/chromevox.gni index 99c15e1..8d8ff392 100644 --- a/chrome/browser/resources/chromeos/chromevox/chromevox.gni +++ b/chrome/browser/resources/chromeos/chromevox/chromevox.gni
@@ -128,6 +128,7 @@ "cvox2/background/classic_compatibility.js", "cvox2/background/cursors.js", "cvox2/background/earcon_engine.js", + "cvox2/background/next_earcons.js", "cvox2/background/output.js", "extensions/searchvox/abstract_result.js", "extensions/searchvox/constants.js", @@ -139,8 +140,8 @@ "extensions/searchvox/util.js", "host/chrome/braille.js", "host/chrome/braille_background.js", + "host/chrome/classic_earcons.js", "host/chrome/earcons.js", - "host/chrome/earcons_background.js", "host/chrome/extension_bridge.js", "host/chrome/host.js", "host/chrome/mathjax.js",
diff --git a/chrome/browser/resources/chromeos/chromevox/chromevox/background/background.js b/chrome/browser/resources/chromeos/chromevox/chromevox/background/background.js index 9393c4a..4af0e42 100644 --- a/chrome/browser/resources/chromeos/chromevox/chromevox/background/background.js +++ b/chrome/browser/resources/chromeos/chromevox/chromevox/background/background.js
@@ -15,9 +15,9 @@ goog.require('cvox.ChromeVox'); goog.require('cvox.ChromeVoxEditableTextBase'); goog.require('cvox.ChromeVoxPrefs'); +goog.require('cvox.ClassicEarcons'); goog.require('cvox.CompositeTts'); goog.require('cvox.ConsoleTts'); -goog.require('cvox.EarconsBackground'); goog.require('cvox.ExtensionBridge'); goog.require('cvox.HostFactory'); goog.require('cvox.InjectedScriptLoader'); @@ -75,7 +75,6 @@ .add(this.backgroundTts_) .add(consoleTts); - this.earcons = new cvox.EarconsBackground(); this.addBridgeListener(); /** @@ -85,13 +84,14 @@ */ this.backgroundBraille_ = new cvox.BrailleBackground(); - this.tabsApiHandler_ = new cvox.TabsApiHandler( - this.tts, this.backgroundBraille_, this.earcons); + this.tabsApiHandler_ = new cvox.TabsApiHandler(); // Export globals on cvox.ChromeVox. cvox.ChromeVox.tts = this.tts; cvox.ChromeVox.braille = this.backgroundBraille_; - cvox.ChromeVox.earcons = this.earcons; + + if (!cvox.ChromeVox.earcons) + cvox.ChromeVox.earcons = new cvox.ClassicEarcons(); if (cvox.ChromeVox.isChromeOS && chrome.accessibilityPrivate.onIntroduceChromeVox) { @@ -264,7 +264,7 @@ */ cvox.ChromeVoxBackground.prototype.onEarconMessage = function(msg) { if (msg.action == 'play') { - this.earcons.playEarcon(msg.earcon); + cvox.ChromeVox.earcons.playEarcon(msg.earcon); } }; @@ -328,7 +328,7 @@ false); } } else if (msg['pref'] == 'earcons') { - this.earcons.enabled = msg['value']; + cvox.AbstractEarcons.enabled = msg['value']; } else if (msg['pref'] == 'sticky' && msg['announce']) { if (msg['value']) { this.tts.speak(Msgs.getMsg('sticky_mode_enabled'),
diff --git a/chrome/browser/resources/chromeos/chromevox/chromevox/background/tabs_api_handler.js b/chrome/browser/resources/chromeos/chromevox/chromevox/background/tabs_api_handler.js index 4719c15..b776438 100644 --- a/chrome/browser/resources/chromeos/chromevox/chromevox/background/tabs_api_handler.js +++ b/chrome/browser/resources/chromeos/chromevox/chromevox/background/tabs_api_handler.js
@@ -19,19 +19,8 @@ /** * Class that adds listeners and handles events from the tabs API. * @constructor - * @param {cvox.TtsInterface} tts The TTS to use for speaking. - * @param {cvox.BrailleInterface} braille The braille interface to use for - * brailling. - * @param {cvox.AbstractEarcons} earcons The earcons object to use for playing - * earcons. */ -cvox.TabsApiHandler = function(tts, braille, earcons) { - /** @type {cvox.TtsInterface} @private */ - this.tts_ = tts; - /** @type {cvox.BrailleInterface} @private */ - this.braille_ = braille; - /** @type {cvox.AbstractEarcons} @private */ - this.earcons_ = earcons; +cvox.TabsApiHandler = function() { /** @type {function(string, Array<string>=)} @private */ this.msg_ = Msgs.getMsg.bind(Msgs); /** @@ -57,12 +46,12 @@ if (!cvox.ChromeVox.isActive) { return; } - this.tts_.speak(this.msg_('chrome_tab_created'), - cvox.QueueMode.FLUSH, - cvox.AbstractTts.PERSONALITY_ANNOUNCEMENT); - this.braille_.write( + cvox.ChromeVox.tts.speak(this.msg_('chrome_tab_created'), + cvox.QueueMode.FLUSH, + cvox.AbstractTts.PERSONALITY_ANNOUNCEMENT); + cvox.ChromeVox.braille.write( cvox.NavBraille.fromText(this.msg_('chrome_tab_created'))); - this.earcons_.playEarcon(cvox.Earcon.OBJECT_OPEN); + cvox.ChromeVox.earcons.playEarcon(cvox.Earcon.OBJECT_OPEN); }, /** @@ -73,7 +62,7 @@ if (!cvox.ChromeVox.isActive) { return; } - this.earcons_.playEarcon(cvox.Earcon.OBJECT_CLOSE); + cvox.ChromeVox.earcons.playEarcon(cvox.Earcon.OBJECT_CLOSE); }, /** @@ -90,13 +79,13 @@ return; } var title = tab.title ? tab.title : tab.url; - this.tts_.speak(this.msg_('chrome_tab_selected', - [title]), - cvox.QueueMode.FLUSH, - cvox.AbstractTts.PERSONALITY_ANNOUNCEMENT); - this.braille_.write( + cvox.ChromeVox.tts.speak(this.msg_('chrome_tab_selected', + [title]), + cvox.QueueMode.FLUSH, + cvox.AbstractTts.PERSONALITY_ANNOUNCEMENT); + cvox.ChromeVox.braille.write( cvox.NavBraille.fromText(this.msg_('chrome_tab_selected', [title]))); - this.earcons_.playEarcon(cvox.Earcon.OBJECT_SELECT); + cvox.ChromeVox.earcons.playEarcon(cvox.Earcon.OBJECT_SELECT); }.bind(this)); }, @@ -115,10 +104,10 @@ } if (tab.status == 'loading') { this.lastActiveTabLoaded_ = false; - this.earcons_.playEarcon(cvox.Earcon.PAGE_START_LOADING); + cvox.ChromeVox.earcons.playEarcon(cvox.Earcon.PAGE_START_LOADING); } else if (!this.lastActiveTabLoaded_) { this.lastActiveTabLoaded_ = true; - this.earcons_.playEarcon(cvox.Earcon.PAGE_FINISH_LOADING); + cvox.ChromeVox.earcons.playEarcon(cvox.Earcon.PAGE_FINISH_LOADING); } }.bind(this)); }, @@ -140,12 +129,12 @@ 'chrome_normal_window_selected'; var tab = tabs[0] || {}; var title = tab.title ? tab.title : tab.url; - this.tts_.speak(this.msg_(msgId, [title]), - cvox.QueueMode.FLUSH, - cvox.AbstractTts.PERSONALITY_ANNOUNCEMENT); - this.braille_.write( + cvox.ChromeVox.tts.speak(this.msg_(msgId, [title]), + cvox.QueueMode.FLUSH, + cvox.AbstractTts.PERSONALITY_ANNOUNCEMENT); + cvox.ChromeVox.braille.write( cvox.NavBraille.fromText(this.msg_(msgId, [title]))); - this.earcons_.playEarcon(cvox.Earcon.OBJECT_SELECT); + cvox.ChromeVox.earcons.playEarcon(cvox.Earcon.OBJECT_SELECT); }.bind(this)); }.bind(this)); }
diff --git a/chrome/browser/resources/chromeos/chromevox/chromevox/injected/console_tts.js b/chrome/browser/resources/chromeos/chromevox/chromevox/injected/console_tts.js index 306ab27..caa3559 100644 --- a/chrome/browser/resources/chromeos/chromevox/chromevox/injected/console_tts.js +++ b/chrome/browser/resources/chromeos/chromevox/chromevox/injected/console_tts.js
@@ -41,7 +41,7 @@ logStr += ' category=' + properties.category; } logStr += ' "' + textString + '"'; - window['console']['log'](logStr); + console.log(logStr); } return this; }; @@ -52,7 +52,7 @@ /** @override */ cvox.ConsoleTts.prototype.stop = function() { if (this.enabled_) { - window['console']['log']('Stop'); + console.log('Stop'); } };
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js index 0a32096..0e2eb11 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js
@@ -13,11 +13,13 @@ goog.require('AutomationPredicate'); goog.require('AutomationUtil'); goog.require('ClassicCompatibility'); +goog.require('NextEarcons'); goog.require('Output'); goog.require('Output.EventType'); goog.require('cursors.Cursor'); goog.require('cvox.BrailleKeyCommand'); goog.require('cvox.ChromeVoxEditableTextBase'); +goog.require('cvox.ClassicEarcons'); goog.require('cvox.ExtensionBridge'); goog.require('cvox.NavBraille'); @@ -115,6 +117,25 @@ break; } }.bind(this)); + + /** @type {!cvox.AbstractEarcons} @private */ + this.classicEarcons_ = cvox.ChromeVox.earcons || new cvox.ClassicEarcons(); + + /** @type {!cvox.AbstractEarcons} @private */ + this.nextEarcons_ = new NextEarcons(); + + // Turn cvox.ChromeVox.earcons into a getter that returns either the + // Next earcons or the Classic earcons depending on the current mode. + Object.defineProperty(cvox.ChromeVox, 'earcons', { + get: (function() { + if (this.mode_ === ChromeVoxMode.FORCE_NEXT || + this.mode_ === ChromeVoxMode.NEXT) { + return this.nextEarcons_; + } else { + return this.classicEarcons_; + } + }).bind(this) + }); }; Background.prototype = {
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/background_test.extjs b/chrome/browser/resources/chromeos/chromevox/cvox2/background/background_test.extjs index a795073..80bb9bf 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/background_test.extjs +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/background_test.extjs
@@ -396,3 +396,49 @@ nonEditable.focus(); }.bind(this)); }); + +TEST_F('BackgroundTest', 'EarconsForControls', function() { + var mockFeedback = this.createMockFeedback(); + this.runWithLoadedTree( + function() {/*! + <p>Initial focus will be on something that's not a control.</p> + <a href="#">MyLink</a> + <button>MyButton</button> + <input type=checkbox> + <input type=checkbox checked> + <input> + <select multiple><option>1</option></select> + <select><option>2</option></select> + <input type=range value=5> + */}, + function(rootNode) { + var doCmd = this.doCmd.bind(this); + + mockFeedback.call(doCmd('nextElement')) + .expectSpeech('MyLink') + .expectEarcon(cvox.Earcon.LINK) + .call(doCmd('nextElement')) + .expectSpeech('MyButton') + .expectEarcon(cvox.Earcon.BUTTON) + .call(doCmd('nextElement')) + .expectSpeech('Check box') + .expectEarcon(cvox.Earcon.CHECK_OFF) + .call(doCmd('nextElement')) + .expectSpeech('Check box') + .expectEarcon(cvox.Earcon.CHECK_ON) + .call(doCmd('nextElement')) + .expectSpeech('Edit text') + .expectEarcon(cvox.Earcon.EDITABLE_TEXT) + .call(doCmd('nextElement')) + .expectSpeech('List box') + .expectEarcon(cvox.Earcon.LISTBOX) + .call(doCmd('nextElement')) + .expectSpeech('Button', 'has pop up') + .expectEarcon(cvox.Earcon.POP_UP_BUTTON) + .call(doCmd('nextElement')) + .expectSpeech(/slider/) + .expectEarcon(cvox.Earcon.SLIDER); + + mockFeedback.replay(); + }.bind(this)); +});
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/earcon_engine.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/earcon_engine.js index fc428c5..83fd6b55 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/earcon_engine.js +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/earcon_engine.js
@@ -18,7 +18,7 @@ // Public control parameters. All of these are meant to be adjustable. /** @type {number} The master volume, as an amplification factor. */ - this.masterVolume = 0.2; + this.masterVolume = 1.0; /** @type {number} The base relative pitch adjustment, in half-steps. */ this.masterPitch = -4;
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/next_earcons.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/next_earcons.js new file mode 100644 index 0000000..519edc6 --- /dev/null +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/next_earcons.js
@@ -0,0 +1,121 @@ +// 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. + +/** + * @fileoverview Earcons library that uses EarconEngine to play back + * auditory cues. + */ + + +goog.provide('NextEarcons'); + +goog.require('EarconEngine'); +goog.require('cvox.AbstractEarcons'); +goog.require('cvox.HostFactory'); + + +/** + * @constructor + * @extends {cvox.AbstractEarcons} + */ +NextEarcons = function() { + cvox.AbstractEarcons.call(this); + + if (localStorage['earcons'] === 'false') { + cvox.AbstractEarcons.enabled = false; + } + + /** + * @type {EarconEngine} + * @private + */ + this.engine_ = new EarconEngine(); +}; + +NextEarcons.prototype = { + /** + * @return {string} The human-readable name of the earcon set. + */ + getName: function() { + return 'ChromeVox Next earcons'; + }, + + /** + * @override + */ + playEarcon: function(earcon) { + if (!cvox.AbstractEarcons.enabled) { + return; + } + console.log('Earcon ' + earcon); + + switch (earcon) { + case cvox.Earcon.ALERT_MODAL: + case cvox.Earcon.ALERT_NONMODAL: + this.engine_.onAlert(); + break; + case cvox.Earcon.BUTTON: + this.engine_.onButton(); + break; + case cvox.Earcon.CHECK_OFF: + this.engine_.onCheckOff(); + break; + case cvox.Earcon.CHECK_ON: + this.engine_.onCheckOn(); + break; + case cvox.Earcon.EDITABLE_TEXT: + this.engine_.onTextField(); + break; + case cvox.Earcon.INVALID_KEYPRESS: + this.engine_.onWrap(); + break; + case cvox.Earcon.LINK: + this.engine_.onLink(); + break; + case cvox.Earcon.LISTBOX: + this.engine_.onSelect(); + break; + case cvox.Earcon.LIST_ITEM: + case cvox.Earcon.LONG_DESC: + case cvox.Earcon.MATH: + case cvox.Earcon.OBJECT_CLOSE: + case cvox.Earcon.OBJECT_ENTER: + case cvox.Earcon.OBJECT_EXIT: + case cvox.Earcon.OBJECT_OPEN: + case cvox.Earcon.OBJECT_SELECT: + // TODO(dmazzoni): decide if we want new earcons for these + // or not. We may choose to not have earcons for some of these. + break; + case cvox.Earcon.PAGE_FINISH_LOADING: + this.engine_.cancelProgress(); + break; + case cvox.Earcon.PAGE_START_LOADING: + // TODO(dmazzoni): only when the page has focus. + this.engine_.startProgress(); + break; + case cvox.Earcon.POP_UP_BUTTON: + this.engine_.onPopUpButton(); + break; + case cvox.Earcon.RECOVER_FOCUS: + // TODO(dmazzoni): decide if we want new earcons for this. + break; + case cvox.Earcon.SELECTION: + this.engine_.onSelection(); + break; + case cvox.Earcon.SELECTION_REVERSE: + this.engine_.onSelectionReverse(); + break; + case cvox.Earcon.SKIP: + this.engine_.onSkim(); + break; + case cvox.Earcon.SLIDER: + this.engine_.onSlider(); + break; + case cvox.Earcon.WRAP: + case cvox.Earcon.WRAP_EDGE: + this.engine_.onWrap(); + break; + } + } +};
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js index af35f3a..715120b 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js
@@ -215,13 +215,16 @@ msgId: 'role_menubar', }, menuItem: { - msgId: 'role_menuitem' + msgId: 'role_menuitem', + earconId: 'BUTTON' }, menuItemCheckBox: { - msgId: 'role_menuitemcheckbox' + msgId: 'role_menuitemcheckbox', + earconId: 'BUTTON' }, menuItemRadio: { - msgId: 'role_menuitemradio' + msgId: 'role_menuitemradio', + earconId: 'BUTTON' }, menuListOption: { msgId: 'role_menuitem' @@ -239,7 +242,6 @@ }, popUpButton: { msgId: 'role_button', - earcon: 'LISTBOX' }, radioButton: { msgId: 'role_radio' @@ -321,15 +323,12 @@ Output.STATE_INFO_ = { checked: { on: { - earconId: 'CHECK_ON', msgId: 'checkbox_checked_state' }, off: { - earconId: 'CHECK_OFF', msgId: 'checkbox_unchecked_state' }, omitted: { - earconId: 'CHECK_OFF', msgId: 'checkbox_unchecked_state' } }, @@ -395,7 +394,8 @@ enter: '@column_granularity $tableCellColumnIndex' }, checkBox: { - speak: '$name $role $checked' + speak: '$if($checked, $earcon(CHECK_ON), $earcon(CHECK_OFF)) ' + + '$name $role $checked' }, dialog: { enter: '$name $role' @@ -446,7 +446,7 @@ speak: '$descendants' }, popUpButton: { - speak: '$value $name $role @aria_has_popup ' + + speak: '$earcon(POP_UP_BUTTON) $value $name $role @aria_has_popup ' + '$if($collapsed, @aria_expanded_false, @aria_expanded_true)' }, radioButton: { @@ -463,7 +463,7 @@ enter: '@row_granularity $tableRowIndex' }, slider: { - speak: '@describe_slider($value, $name) $help' + speak: '$earcon(SLIDER) @describe_slider($value, $name) $help' }, staticText: { speak: '$value=' @@ -690,27 +690,25 @@ var queueMode = this.speechProperties_['category'] ? cvox.QueueMode.CATEGORY_FLUSH : cvox.QueueMode.FLUSH; this.speechBuffer_.forEach(function(buff, i, a) { - if (buff.toString()) { - (function() { - var scopedBuff = buff; - this.speechProperties_['startCallback'] = function() { - var actions = scopedBuff.getSpansInstanceOf(Output.Action); - if (actions) { - actions.forEach(function(a) { - a.run(); - }); - } - }; - }.bind(this)()); + (function() { + var scopedBuff = buff; + this.speechProperties_['startCallback'] = function() { + var actions = scopedBuff.getSpansInstanceOf(Output.Action); + if (actions) { + actions.forEach(function(a) { + a.run(); + }); + } + }; + }.bind(this)()); - if (this.speechEndCallback_ && i == a.length - 1) - this.speechProperties_['endCallback'] = this.speechEndCallback_; - else - this.speechProperties_['endCallback'] = null; - cvox.ChromeVox.tts.speak( - buff.toString(), queueMode, this.speechProperties_); - queueMode = cvox.QueueMode.QUEUE; - } + if (this.speechEndCallback_ && i == a.length - 1) + this.speechProperties_['endCallback'] = this.speechEndCallback_; + else + this.speechProperties_['endCallback'] = null; + cvox.ChromeVox.tts.speak( + buff.toString(), queueMode, this.speechProperties_); + queueMode = cvox.QueueMode.QUEUE; }.bind(this)); // Braille. @@ -967,13 +965,10 @@ // Ignore unless we're generating speech output. if (!this.formatOptions_.speech) return; - // Assumes there's existing output in our buffer. - var lastBuff = buff[buff.length - 1]; - if (!lastBuff) - return; - lastBuff.setSpan( - new Output.EarconAction(tree.firstChild.value), 0, 0); + options.annotation.push( + new Output.EarconAction(tree.firstChild.value)); + this.append_(buff, '', options); } else if (token == 'countChildren') { var role = tree.firstChild.value; var count = node.children.filter(function(e) {
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/output_test.extjs b/chrome/browser/resources/chromeos/chromevox/cvox2/background/output_test.extjs index ad642ed0..a6940a7 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/output_test.extjs +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/output_test.extjs
@@ -108,14 +108,14 @@ var el = root.firstChild.firstChild; var range = cursors.Range.fromNode(el); var o = new Output().withSpeechAndBraille(range, null, 'navigate'); - assertEqualsJSON({string_: '|Check box|not checked', 'spans_': [ - // Attributes. - {value: 'name', start: 0, end: 0}, - {value: 'role', start: 1, end: 10}, - {value: 'state', start: 11, end: 22}, - + assertEqualsJSON({string_: '||Check box|not checked', 'spans_': [ // Checkbox earcon (based on the state). - {value: {earconId: 'CHECK_OFF'}, start: 11, end: 22} + {value: {earconId: 'CHECK_OFF'}, start: 0, end: 0}, + + // Attributes. + {value: 'name', start: 1, end: 1}, + {value: 'role', start: 2, end: 11}, + {value: 'state', start: 12, end: 23} ]}, o.speechOutputForTest); checkBrailleOutput( 'chk ( )', @@ -223,9 +223,10 @@ var prevRange = range; range = cursors.Range.fromNode(el); var o = new Output().withSpeechAndBraille(range, prevRange, 'navigate'); - assertEqualsJSON({string_: '0, , slider|audio time scrubber', + assertEqualsJSON({string_: '|0, , slider|audio time scrubber', spans_: - [{value: 'help', start: 12, end: 31}] + [{value: {'earconId': 'SLIDER'}, start: 0, end: 0}, + {value: 'help', start: 13, end: 32}] }, o.speechOutputForTest); // TODO(plundblad): Investigate this. checkBrailleOutput( @@ -453,6 +454,7 @@ assertEqualsJSON({string_: '|Menu|with 1 item|a|Menu item| 1 of 1 ', spans_: [ {value: 'name', start: 18, end: 19}, + {value: {earconId: 'BUTTON'}, start:18, end:19}, {value: 'role', start:20, end: 29} ]}, o.speechOutputForTest); checkBrailleOutput(
diff --git a/chrome/browser/resources/chromeos/chromevox/host/chrome/earcons_background.js b/chrome/browser/resources/chromeos/chromevox/host/chrome/classic_earcons.js similarity index 68% rename from chrome/browser/resources/chromeos/chromevox/host/chrome/earcons_background.js rename to chrome/browser/resources/chromeos/chromevox/host/chrome/classic_earcons.js index 500da1a1..d1729c9 100644 --- a/chrome/browser/resources/chromeos/chromevox/host/chrome/earcons_background.js +++ b/chrome/browser/resources/chromeos/chromevox/host/chrome/classic_earcons.js
@@ -9,7 +9,7 @@ */ -goog.provide('cvox.EarconsBackground'); +goog.provide('cvox.ClassicEarcons'); goog.require('cvox.AbstractEarcons'); @@ -18,21 +18,22 @@ * @constructor * @extends {cvox.AbstractEarcons} */ -cvox.EarconsBackground = function() { +cvox.ClassicEarcons = function() { goog.base(this); - this.audioMap = new Object(); if (localStorage['earcons'] === 'false') { - this.enabled = false; + cvox.AbstractEarcons.enabled = false; } + + this.audioMap = new Object(); }; -goog.inherits(cvox.EarconsBackground, cvox.AbstractEarcons); +goog.inherits(cvox.ClassicEarcons, cvox.AbstractEarcons); /** * @return {string} The human-readable name of the earcon set. */ -cvox.EarconsBackground.prototype.getName = function() { +cvox.ClassicEarcons.prototype.getName = function() { return 'ChromeVox earcons'; }; @@ -40,22 +41,20 @@ /** * @return {string} The base URL for loading earcons. */ -cvox.EarconsBackground.prototype.getBaseUrl = function() { - return cvox.EarconsBackground.BASE_URL; +cvox.ClassicEarcons.prototype.getBaseUrl = function() { + return cvox.ClassicEarcons.BASE_URL; }; /** * @override */ -cvox.EarconsBackground.prototype.playEarcon = function(earcon) { +cvox.ClassicEarcons.prototype.playEarcon = function(earcon) { goog.base(this, 'playEarcon', earcon); - if (!this.enabled) { + if (!cvox.AbstractEarcons.enabled) { return; } - if (window['console']) { - window['console']['log']('Earcon ' + earcon); - } + console.log('Earcon ' + earcon); this.currentAudio = this.audioMap[earcon]; if (!this.currentAudio) { @@ -78,4 +77,4 @@ * The base URL for loading eracons. * @type {string} */ -cvox.EarconsBackground.BASE_URL = 'chromevox/background/earcons/'; +cvox.ClassicEarcons.BASE_URL = 'chromevox/background/earcons/';
diff --git a/chrome/browser/resources/chromeos/chromevox/host/chrome/earcons.js b/chrome/browser/resources/chromeos/chromevox/host/chrome/earcons.js index c250e8c39..5ac0f81 100644 --- a/chrome/browser/resources/chromeos/chromevox/host/chrome/earcons.js +++ b/chrome/browser/resources/chromeos/chromevox/host/chrome/earcons.js
@@ -31,7 +31,7 @@ */ cvox.ChromeEarcons.prototype.playEarcon = function(earcon) { goog.base(this, 'playEarcon', earcon); - if (!this.enabled) { + if (!cvox.AbstractEarcons.enabled) { return; } @@ -51,9 +51,9 @@ 'target': 'Prefs', 'action': 'setPref', 'pref': 'earcons', - 'value': this.enabled + 'value': cvox.AbstractEarcons.enabled }); - if (!this.enabled) { + if (!cvox.AbstractEarcons.enabled) { cvox.ChromeVox.host.sendToBackgroundPage({ 'target': 'Prefs', 'action': 'setPref', @@ -61,8 +61,11 @@ 'value': true }); } - return this.enabled; + return cvox.AbstractEarcons.enabled; }; +/** + * @override + */ cvox.HostFactory.earconsConstructor = cvox.ChromeEarcons;
diff --git a/chrome/browser/resources/chromeos/chromevox/host/chrome/host.js b/chrome/browser/resources/chromeos/chromevox/host/chrome/host.js index b44711bf..f6db51cd 100644 --- a/chrome/browser/resources/chromeos/chromevox/host/chrome/host.js +++ b/chrome/browser/resources/chromeos/chromevox/host/chrome/host.js
@@ -62,9 +62,6 @@ cvox.ChromeVox.version = prefs['version']; - cvox.ChromeVox.earcons.enabled = - /** @type {boolean} */(JSON.parse(prefs['earcons'])); - cvox.ChromeVox.typingEcho = /** @type {number} */(JSON.parse(prefs['typingEcho']));
diff --git a/chrome/browser/resources/chromeos/chromevox/host/interface/abstract_earcons.js b/chrome/browser/resources/chromeos/chromevox/host/interface/abstract_earcons.js index 1dabd1a..c1c5dd1 100644 --- a/chrome/browser/resources/chromeos/chromevox/host/interface/abstract_earcons.js +++ b/chrome/browser/resources/chromeos/chromevox/host/interface/abstract_earcons.js
@@ -37,10 +37,12 @@ OBJECT_SELECT: 'object_select', PAGE_FINISH_LOADING: 'page_finish_loading', PAGE_START_LOADING: 'page_start_loading', + POP_UP_BUTTON: 'pop_up_button', RECOVER_FOCUS: 'recover_focus', SELECTION: 'selection', SELECTION_REVERSE: 'selection_reverse', SKIP: 'skip', + SLIDER: 'slider', WRAP: 'wrap', WRAP_EDGE: 'wrap_edge', }; @@ -50,16 +52,18 @@ * @constructor */ cvox.AbstractEarcons = function() { - /** - * Public flag set to enable or disable earcons. Callers should prefer - * toggle(); however, this member is public for initialization. - * @type {boolean} - */ - this.enabled = true; }; /** + * Public static flag set to enable or disable earcons. Callers should prefer + * toggle(); however, this member is public for initialization. + * @type {boolean} + */ +cvox.AbstractEarcons.enabled = true; + + +/** * Plays the specified earcon sound. * @param {cvox.Earcon} earcon An earcon identifier. */ @@ -81,6 +85,6 @@ * @return {boolean} True if earcons are now enabled; false otherwise. */ cvox.AbstractEarcons.prototype.toggle = function() { - this.enabled = !this.enabled; - return this.enabled; + cvox.AbstractEarcons.enabled = !cvox.AbstractEarcons.enabled; + return cvox.AbstractEarcons.enabled; };
diff --git a/chrome/browser/resources/chromeos/chromevox/testing/mock_feedback.js b/chrome/browser/resources/chromeos/chromevox/testing/mock_feedback.js index e3578aa0..4c846e8 100644 --- a/chrome/browser/resources/chromeos/chromevox/testing/mock_feedback.js +++ b/chrome/browser/resources/chromeos/chromevox/testing/mock_feedback.js
@@ -3,18 +3,20 @@ // found in the LICENSE file. /** - * @fileoverview This file contains the |MockFeedback| class which is a - * combined mock class for speech and braille feedback. A test that uses - * this class may add expectations for speech utterances and braille display - * content to be output. The |install| method sets appropriate mock classes - * as the |cvox.ChromeVox.tts| and |cvox.ChromeVox.braille| objects, - * respectively. Output sent to those objects will then be collected in - * an internal queue. + * @fileoverview This file contains the |MockFeedback| class which is + * a combined mock class for speech, braille, and earcon feedback. A + * test that uses this class may add expectations for speech + * utterances, braille display content to be output, and earcons + * played (by name). The |install| method sets appropriate mock + * classes as the |cvox.ChromeVox.tts|, |cvox.ChromeVox.braille| and + * |cvox.ChromeVox.earcons| objects, respectively. Output sent to + * those objects will then be collected in an internal queue. * - * Expectations can be added using the |expectSpeech| and |expectBraille| - * methods. These methods take either strings or regular expressions to match - * against. Strings must match a full utterance (or display content) exactly, - * while a regular expression must match a substring (use anchor operators if + * Expectations can be added using the |expectSpeech|, + * |expectBraille|, and |expectEarcon| methods. These methods take + * either strings or regular expressions to match against. Strings + * must match a full utterance (or display content) exactly, while a + * regular expression must match a substring (use anchor operators if * needed). * * Function calls may be inserted in the stream of expectations using the @@ -22,11 +24,11 @@ * have been met, and before any further expectations are matched. Callbacks * are called in the order they were added to the mock. * - * The |replay| method starts processing any pending utterances and braille - * display content and will try to match expectations as new feedback enters - * the queue asynchronously. When all expectations have been met and callbacks - * called, the finish callback, if any was provided to the constructor, is - * called. + * The |replay| method starts processing any pending utterances, + * braille display content, and earcons and will try to match + * expectations as new feedback enters the queue asynchronously. When + * all expectations have been met and callbacks called, the finish + * callback, if any was provided to the constructor, is called. * * This mock class is lean, meaning that feedback that doesn't match * any expectations is silently ignored. @@ -82,6 +84,12 @@ */ this.pendingBraille_ = []; /** + * Pending earcons. + * @type {Array<{text: string, callback: (function|undefined)}>} + * @private + */ + this.pendingEarcons_ = []; + /** * Handle for the timeout set for debug logging. * @type {number} * @private @@ -118,6 +126,17 @@ }; cvox.ChromeVox.braille = new MockBraille(); + + var MockEarcons = function() {}; + MockEarcons.prototype = { + __proto__: cvox.AbstractEarcons.prototype, + playEarcon: this.addEarcon_.bind(this) + }; + + // cvox.ChromeVox.earcons is a getter that switches between Classic and + // Next; replace it with MockEarcons. + delete cvox.ChromeVox.earcons; + cvox.ChromeVox.earcons = new MockEarcons(); }, /** @@ -197,6 +216,26 @@ }, /** + * Adds an expectation for a played earcon. + * @param {string} earconName The name of the earcon. + * @return {MockFeedback} |this| for chaining + */ + expectEarcon: function(earconName, opt_props) { + assertFalse(this.replaying_); + this.pendingActions_.push({ + perform: function() { + var match = MockFeedback.matchAndConsume_( + earconName, {}, this.pendingEarcons_); + return !!match; + }.bind(this), + toString: function() { + return 'Earcon \'' + earconName + '\''; + } + }); + return this; + }, + + /** * Arranges for a callback to be invoked when all expectations that were * added before this call have been met. Callbacks are called in the * order they are added. @@ -270,6 +309,12 @@ this.process_(); }, + /** @private */ + addEarcon_: function(earconName) { + this.pendingEarcons_.push({text: earconName}); + this.process_(); + }, + /*** @private */ process_: function() { if (!this.replaying_ || this.inProcess_) @@ -324,6 +369,7 @@ } logPending('speech utterances', this.pendingUtterances_); logPending('braille', this.pendingBraille_); + logPending('earcons', this.pendingEarcons_); this.logTimeoutId_ = 0; }, }; @@ -338,7 +384,10 @@ */ MockFeedback.matchAndConsume_ = function(text, props, pending) { for (var i = 0, candidate; candidate = pending[i]; ++i) { - var candidateText = candidate.text.toString(); + var candidateText = candidate.text; + if (typeof(candidateText) != 'string') + candidateText = candidateText.toString(); + if (text === candidateText || (text instanceof RegExp && text.test(candidateText))) { var matched = true;
diff --git a/chrome/browser/resources/chromeos/chromevox/testing/mock_feedback_test.unitjs b/chrome/browser/resources/chromeos/chromevox/testing/mock_feedback_test.unitjs index 77c8220..5466b773 100644 --- a/chrome/browser/resources/chromeos/chromevox/testing/mock_feedback_test.unitjs +++ b/chrome/browser/resources/chromeos/chromevox/testing/mock_feedback_test.unitjs
@@ -4,7 +4,7 @@ // Include test fixture. GEN_INCLUDE(['chromevox_unittest_base.js', - 'mock_feedback.js']); + 'mock_feedback.js']); function speak(text, opt_properties) { cvox.ChromeVox.tts.speak(text, 0, opt_properties); @@ -16,6 +16,10 @@ return navBraille; } +function earcon(earconName) { + cvox.ChromeVox.earcons.playEarcon(cvox.Earcon[earconName]); +} + /** * Test fixture. * @constructor @@ -36,7 +40,8 @@ closureModuleDeps: [ 'cvox.BrailleInterface', 'cvox.NavBraille', - 'cvox.TtsInterface' + 'cvox.TtsInterface', + 'cvox.AbstractEarcons' ] }; @@ -170,3 +175,27 @@ .replay(); assertTrue(firstCallbackCalled); }); + +TEST_F('MockFeedbackUnitTest', 'SpeechAndEarcons', function() { + var finishCalled = false; + var mock = new MockFeedback(function() { finishCalled = true; }); + mock.install(); + mock.call(function() { + speak('MyButton', {startCallback: function() { + earcon('BUTTON'); + }}); + }) + .expectSpeech('MyButton') + .expectEarcon(cvox.Earcon.BUTTON) + .call(function() { + earcon('ALERT_MODAL'); + speak('MyTextField', {startCallback: function() { + earcon('EDITABLE_TEXT'); + }}); + }) + .expectEarcon(cvox.Earcon.ALERT_MODAL) + .expectSpeech('MyTextField') + .expectEarcon(cvox.Earcon.EDITABLE_TEXT) + .replay(); + assertTrue(finishCalled); +});
diff --git a/chrome/browser/resources/extensions/compiled_resources.gyp b/chrome/browser/resources/extensions/compiled_resources.gyp index a40ae06..7779b4e 100644 --- a/chrome/browser/resources/extensions/compiled_resources.gyp +++ b/chrome/browser/resources/extensions/compiled_resources.gyp
@@ -32,9 +32,9 @@ 'focus_row.js', ], 'externs': [ - '<(EXTERNS_DIR)/chrome_extensions.js', '<(EXTERNS_DIR)/chrome_send.js', '<(EXTERNS_DIR)/developer_private.js', + '<(EXTERNS_DIR)/management.js', ], }, 'includes': ['../../../../third_party/closure_compiler/compile_js.gypi'],
diff --git a/chrome/browser/resources/extensions/extension_command_list.js b/chrome/browser/resources/extensions/extension_command_list.js index 9974fb7..49e05301 100644 --- a/chrome/browser/resources/extensions/extension_command_list.js +++ b/chrome/browser/resources/extensions/extension_command_list.js
@@ -2,16 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -/** @typedef {{active: boolean, - * command_name: string, - * description: string, - * extension_action: boolean, - * extension_id: string, - * global: boolean, - * keybinding: string}} - */ -var ExtensionCommand; - cr.define('options', function() { 'use strict'; @@ -217,10 +207,11 @@ /** * Updates the extensions data for the overlay. - * @param {!Array<ExtensionInfo>} data The extension data. + * @param {!Array<chrome.developerPrivate.ExtensionInfo>} data The extension + * data. */ setData: function(data) { - /** @private {!Array<ExtensionInfo>} */ + /** @private {!Array<chrome.developerPrivate.ExtensionInfo>} */ this.data_ = data; this.textContent = ''; @@ -232,7 +223,8 @@ /** * Synthesizes and initializes an HTML element for the extension command * metadata given in |extension|. - * @param {ExtensionInfo} extension A dictionary of extension metadata. + * @param {chrome.developerPrivate.ExtensionInfo} extension A dictionary of + * extension metadata. * @private */ createNodeForExtension_: function(extension) { @@ -259,7 +251,8 @@ * Synthesizes and initializes an HTML element for the extension command * metadata given in |command|. * @param {string} extensionId The associated extension's id. - * @param {Command} command A dictionary of extension command metadata. + * @param {chrome.developerPrivate.Command} command A dictionary of + * extension command metadata. * @private */ createNodeForCommand_: function(extensionId, command) {
diff --git a/chrome/browser/resources/extensions/extension_commands_overlay.js b/chrome/browser/resources/extensions/extension_commands_overlay.js index 9b51f34..6e0e43a 100644 --- a/chrome/browser/resources/extensions/extension_commands_overlay.js +++ b/chrome/browser/resources/extensions/extension_commands_overlay.js
@@ -54,7 +54,7 @@ /** * Called by the dom_ui_ to re-populate the page with data representing * the current state of extension commands. - * @param {!Array<ExtensionInfo>} extensionsData + * @param {!Array<chrome.developerPrivate.ExtensionInfo>} extensionsData */ ExtensionCommandsOverlay.updateExtensionsData = function(extensionsData) { var overlay = ExtensionCommandsOverlay.getInstance();
diff --git a/chrome/browser/resources/extensions/extension_error.js b/chrome/browser/resources/extensions/extension_error.js index 9ad71e8..0f50425 100644 --- a/chrome/browser/resources/extensions/extension_error.js +++ b/chrome/browser/resources/extensions/extension_error.js
@@ -195,7 +195,7 @@ /** * The callback for the extension changed event. - * @private {function(EventData):void} + * @private {function(chrome.developerPrivate.EventData):void} */ this.onItemStateChangedListener_ = function(data) { var type = chrome.developerPrivate.EventType;
diff --git a/chrome/browser/resources/extensions/extension_error_overlay.js b/chrome/browser/resources/extensions/extension_error_overlay.js index 1f7975e..3acfef97 100644 --- a/chrome/browser/resources/extensions/extension_error_overlay.js +++ b/chrome/browser/resources/extensions/extension_error_overlay.js
@@ -2,6 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. + +/** @typedef {chrome.developerPrivate.RuntimeError} */ +var RuntimeError; +/** @typedef {chrome.developerPrivate.ManifestError} */ +var ManifestError; + cr.define('extensions', function() { 'use strict'; @@ -465,7 +471,8 @@ /** * Requests a file's source. - * @param {RequestFileSourceProperties} args The arguments for the call. + * @param {chrome.developerPrivate.RequestFileSourceProperties} args The + * arguments for the call. */ requestFileSource: function(args) { chrome.developerPrivate.requestFileSource( @@ -475,10 +482,10 @@ /** * Set the code to be displayed in the code portion of the overlay. * @see ExtensionErrorOverlay.requestFileSourceResponse(). - * @param {?RequestFileSourceResponse} response The response from the - * request file source call, which will be shown as code. If |response| - * is null, then a "Could not display code" message will be displayed - * instead. + * @param {?chrome.developerPrivate.RequestFileSourceResponse} response The + * response from the request file source call, which will be shown as + * code. If |response| is null, then a "Could not display code" message + * will be displayed instead. */ onFileSourceResponse_: function(response) { this.codeDiv_.populate(
diff --git a/chrome/browser/resources/extensions/extension_list.js b/chrome/browser/resources/extensions/extension_list.js index 2bbed63..c59e385 100644 --- a/chrome/browser/resources/extensions/extension_list.js +++ b/chrome/browser/resources/extensions/extension_list.js
@@ -66,8 +66,8 @@ /** * Compares two extensions for the order they should appear in the list. - * @param {ExtensionInfo} a The first extension. - * @param {ExtensionInfo} b The second extension. + * @param {chrome.developerPrivate.ExtensionInfo} a The first extension. + * @param {chrome.developerPrivate.ExtensionInfo} b The second extension. * returns {number} -1 if A comes before B, 1 if A comes after B, 0 if equal. */ function compareExtensions(a, b) { @@ -163,7 +163,7 @@ * @param {!extensions.ExtensionListDelegate} delegate */ initialize: function(delegate) { - /** @private {!Array<ExtensionInfo>} */ + /** @private {!Array<chrome.developerPrivate.ExtensionInfo>} */ this.extensions_ = []; /** @private {!extensions.ExtensionListDelegate} */ @@ -408,7 +408,8 @@ /** * Synthesizes and initializes an HTML element for the extension metadata * given in |extension|. - * @param {!ExtensionInfo} extension A dictionary of extension metadata. + * @param {!chrome.developerPrivate.ExtensionInfo} extension A dictionary + * of extension metadata. * @param {?Element} nextWrapper The newly created wrapper will be inserted * before |nextWrapper| if non-null (else it will be appended to the * wrapper list). @@ -602,7 +603,8 @@ /** * Updates an HTML element for the extension metadata given in |extension|. - * @param {!ExtensionInfo} extension A dictionary of extension metadata. + * @param {!chrome.developerPrivate.ExtensionInfo} extension A dictionary of + * extension metadata. * @param {!Element} wrapper The extension wrapper element to update. * @private */ @@ -1047,8 +1049,8 @@ /** * Updates or creates a wrapper for |extension|. - * @param {!ExtensionInfo} extension The information about the extension to - * update. + * @param {!chrome.developerPrivate.ExtensionInfo} extension The information + * about the extension to update. * @private */ updateOrCreateWrapper_: function(extension) {
diff --git a/chrome/browser/resources/extensions/extensions.js b/chrome/browser/resources/extensions/extensions.js index e957033..ceeea64 100644 --- a/chrome/browser/resources/extensions/extensions.js +++ b/chrome/browser/resources/extensions/extensions.js
@@ -243,7 +243,7 @@ /** * [Re]-Populates the page with data representing the current state of * installed extensions. - * @param {ProfileInfo} profileInfo + * @param {chrome.developerPrivate.ProfileInfo} profileInfo * @private */ update_: function(profileInfo) {
diff --git a/chrome/browser/resources/extensions/pack_extension_overlay.js b/chrome/browser/resources/extensions/pack_extension_overlay.js index 05d23d1..63b20a4d 100644 --- a/chrome/browser/resources/extensions/pack_extension_overlay.js +++ b/chrome/browser/resources/extensions/pack_extension_overlay.js
@@ -97,7 +97,8 @@ /** * Handles a response from a packDirectory call. - * @param {PackDirectoryResponse} response The response of the pack call. + * @param {chrome.developerPrivate.PackDirectoryResponse} response The + * response of the pack call. * @private */ onPackResponse_: function(response) {
diff --git a/chrome/browser/resources/settings/controls/compiled_resources.gyp b/chrome/browser/resources/settings/controls/compiled_resources.gyp index ae603dbc..17cd860d 100644 --- a/chrome/browser/resources/settings/controls/compiled_resources.gyp +++ b/chrome/browser/resources/settings/controls/compiled_resources.gyp
@@ -7,7 +7,10 @@ 'target_name': 'settings_checkbox', 'variables': { 'depends': [ - '../policy_controllable/policy_controllable.js', + '../../../../../ui/webui/resources/js/compiled_resources.gyp:assert', + '../../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data', + '../../../../../ui/webui/resources/cr_elements/v1_0/policy/cr_policy_indicator_behavior.js', + '../../../../../ui/webui/resources/cr_elements/v1_0/policy/cr_policy_pref_behavior.js', ], 'externs': [ '../../../../../third_party/closure_compiler/externs/settings_private.js' @@ -20,7 +23,9 @@ 'variables': { 'depends': [ '../../../../../ui/webui/resources/js/compiled_resources.gyp:assert', - '../policy_controllable/policy_controllable.js', + '../../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data', + '../../../../../ui/webui/resources/cr_elements/v1_0/policy/cr_policy_indicator_behavior.js', + '../../../../../ui/webui/resources/cr_elements/v1_0/policy/cr_policy_pref_behavior.js', ], 'externs': [ '../../../../../third_party/closure_compiler/externs/settings_private.js'
diff --git a/chrome/browser/resources/settings/controls/settings_checkbox.html b/chrome/browser/resources/settings/controls/settings_checkbox.html index 25a3cae..4a279814 100644 --- a/chrome/browser/resources/settings/controls/settings_checkbox.html +++ b/chrome/browser/resources/settings/controls/settings_checkbox.html
@@ -1,8 +1,8 @@ <link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-checkbox/paper-checkbox.html"> <link rel="import" href="chrome://resources/cr_elements/v1_0/cr_events/cr_events.html"> -<link rel="import" href="chrome://resources/cr_elements/v1_0/policy/cr_policy_indicator.html"> -<link rel="import" href="chrome://md-settings/policy_controllable/policy_controllable.html"> +<link rel="import" href="chrome://resources/cr_elements/v1_0/policy/cr_policy_pref_behavior.html"> +<link rel="import" href="chrome://resources/cr_elements/v1_0/policy/cr_policy_pref_indicator.html"> <link rel="import" href="chrome://md-settings/pref_tracker/pref_tracker.html"> <dom-module id="settings-checkbox"> @@ -17,7 +17,7 @@ <span id="mainLabel">{{label}}</span> <span id="subLabel">{{subLabel}}</span> </paper-checkbox> - <cr-policy-indicator pref="[[pref]]"></cr-policy-indicator> + <cr-policy-pref-indicator pref="[[pref]]"></cr-policy-pref-indicator> </div> </template> <script src="settings_checkbox.js"></script>
diff --git a/chrome/browser/resources/settings/controls/settings_checkbox.js b/chrome/browser/resources/settings/controls/settings_checkbox.js index 5a6134b..e892fb9 100644 --- a/chrome/browser/resources/settings/controls/settings_checkbox.js +++ b/chrome/browser/resources/settings/controls/settings_checkbox.js
@@ -16,12 +16,12 @@ Polymer({ is: 'settings-checkbox', - behaviors: [PolicyControllable], + behaviors: [CrPolicyPrefBehavior], properties: { /** * The boolean preference object to control. - * @type {?chrome.settingsPrivate.PrefObject} + * @type {!chrome.settingsPrivate.PrefObject|undefined} */ pref: { type: Object, @@ -101,11 +101,11 @@ /** * @param {boolean} disabled - * @param {?chrome.settingsPrivate.PrefObject} pref + * @param {!chrome.settingsPrivate.PrefObject} pref * @return {boolean} Whether the checkbox should be disabled. * @private */ checkboxDisabled_: function(disabled, pref) { - return disabled || this.isPolicyControlled(pref); + return disabled || this.isPrefPolicyControlled(pref); }, });
diff --git a/chrome/browser/resources/settings/controls/settings_input.html b/chrome/browser/resources/settings/controls/settings_input.html index 3db53397..26f40f5 100644 --- a/chrome/browser/resources/settings/controls/settings_input.html +++ b/chrome/browser/resources/settings/controls/settings_input.html
@@ -1,7 +1,8 @@ <link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input.html"> <link rel="import" href="chrome://resources/cr_elements/v1_0/cr_events/cr_events.html"> -<link rel="import" href="chrome://md-settings/policy_controllable/policy_controllable.html"> +<link rel="import" href="chrome://resources/cr_elements/v1_0/policy/cr_policy_pref_behavior.html"> +<link rel="import" href="chrome://resources/cr_elements/v1_0/policy/cr_policy_pref_indicator.html"> <link rel="import" href="chrome://md-settings/pref_tracker/pref_tracker.html"> <dom-module id="settings-input"> @@ -17,7 +18,7 @@ readonly$="[[readonly]]" required="[[required]]" type="[[type]]" on-blur="onBlur_" disabled="[[isDisabled_(disabled, pref)]]"> </paper-input> - <cr-policy-indicator pref="[[pref]]"></cr-policy-indicator> + <cr-policy-pref-indicator pref="[[pref]]"></cr-policy-pref-indicator> </div> </template> <script src="settings_input.js"></script>
diff --git a/chrome/browser/resources/settings/controls/settings_input.js b/chrome/browser/resources/settings/controls/settings_input.js index 5c1d957..ab0cfe5 100644 --- a/chrome/browser/resources/settings/controls/settings_input.js +++ b/chrome/browser/resources/settings/controls/settings_input.js
@@ -12,12 +12,12 @@ Polymer({ is: 'settings-input', - behaviors: [PolicyControllable], + behaviors: [CrPolicyPrefBehavior], properties: { /** * The preference object to control. - * @type {chrome.settingsPrivate.PrefObject|undefined} + * @type {!chrome.settingsPrivate.PrefObject|undefined} */ pref: { type: Object, @@ -128,11 +128,11 @@ /** * @param {boolean} disabled - * @param {?chrome.settingsPrivate.PrefObject} pref + * @param {!chrome.settingsPrivate.PrefObject} pref * @return {boolean} Whether the element should be disabled. * @private */ isDisabled_: function(disabled, pref) { - return disabled || this.isPolicyControlled(pref); + return disabled || this.isPrefPolicyControlled(pref); }, });
diff --git a/chrome/browser/resources/settings/internet_page/internet_detail_page.css b/chrome/browser/resources/settings/internet_page/internet_detail_page.css index 684a613e..633a05e 100644 --- a/chrome/browser/resources/settings/internet_page/internet_detail_page.css +++ b/chrome/browser/resources/settings/internet_page/internet_detail_page.css
@@ -2,65 +2,48 @@ * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ -#titleDiv { - margin-bottom: 10px; +.section { + margin-bottom: 5px; } -#outerDiv { - margin: 0 40px; +cr-collapse { + margin: 10px; } -#networkIcon { +cr-network-icon { height: 32px; width: 32px; } -#networkName { - -webkit-margin-start: 10px; - font-size: 20px; - font-weight: bold; -} - +#networkName, #networkState { -webkit-margin-start: 10px; font-size: 20px; } +#networkName { + font-weight: bold; +} + #networkState[connected] { color: green; } -#simInfoDiv { - margin-left: 10px; +#outerDiv { + margin: 10px 20px; } -#infoDiv { - margin-left: 10px; -} - -#infoDiv span { - margin-bottom: 8px; +#ipAddressLabel { + -webkit-margin-end: 10px; + font-weight: bold; } #preferButton { - margin: 0 7px 8px -2px; + -webkit-margin-end: 8px; + -webkit-margin-start: -3px; padding: 0 } -#advancedDiv paper-button { - --paper-button: { - text-align: start; - }; -} - #proxyDiv { max-width: 500px; } - -paper-checkbox { - margin-bottom: 10px; -} - -cr-collapse { - margin: 10px; -}
diff --git a/chrome/browser/resources/settings/internet_page/internet_detail_page.html b/chrome/browser/resources/settings/internet_page/internet_detail_page.html index 9304312e..827de6a 100644 --- a/chrome/browser/resources/settings/internet_page/internet_detail_page.html +++ b/chrome/browser/resources/settings/internet_page/internet_detail_page.html
@@ -22,7 +22,7 @@ <div class="layout vertical"> <!-- Title section: Icon + name + connection state. --> <div id="titleDiv" class="layout horizontal center"> - <cr-network-icon id="networkIcon" network-state="[[networkProperties]]"> + <cr-network-icon network-state="[[networkProperties]]"> </cr-network-icon> <span id="networkName">[[getStateName_(networkProperties)]]</span> <span id="networkState" @@ -32,7 +32,7 @@ <div id="outerDiv" class="layout vertical"> <!-- For Cellular, show SIM info first. --> - <div id="simInfoDiv" class="layout vertical"> + <div class="layout vertical section"> <network-siminfo editable hidden$="[[!showCellularSim_(networkProperties)]]" network-properties="[[networkProperties]]" @@ -42,14 +42,16 @@ <!-- Info and properties common to all networks. --> <div id="infoDiv" class="layout vertical"> - <div class="layout horizontal" hidden$="[[!IPAddress]]"> - <span>IP Address:</span> + <div class="layout horizontal section" hidden$="[[!IPAddress]]"> + <span id="ipAddressLabel">IP Address:</span> <span>[[IPAddress]]</span> </div> - <span hidden$="[[!showShared_(networkProperties)]]"> - This network is shared with other users. - </span> - <div class="layout horizontal center" + <div class="section"> + <span hidden$="[[!showShared_(networkProperties)]]"> + This network is shared with other users. + </span> + </div> + <div class="layout horizontal center section" hidden$="[[!showPreferNetwork_(networkProperties)]]"> <paper-icon-button id="preferButton" toggles active="{{preferNetwork}}" @@ -57,20 +59,23 @@ </paper-icon-button> <span>Prefer this network</span> </div> - <paper-checkbox checked="{{autoConnect}}" - hidden$="[[!showAutoConnect_(networkProperties)]]"> - Automatically connect to this network - </paper-checkbox> - + <div class="section"> + <paper-checkbox checked="{{autoConnect}}" + hidden$="[[!showAutoConnect_(networkProperties)]]"> + Automatically connect to this network + </paper-checkbox> + </div> <!-- Properties to always show if present. --> - <network-property-list - fields="[[getInfoFields_(networkProperties)]]" - property-dict="[[networkProperties]]"> - </network-property-list> + <div class="section"> + <network-property-list + fields="[[getInfoFields_(networkProperties)]]" + property-dict="[[networkProperties]]"> + </network-property-list> + </div> </div> <!-- Button row: Advanced + Disconnect | Connect. --> - <div class="layout horizontal center"> + <div id="buttonDiv" class="layout horizontal center"> <paper-button toggles noink active="{{advancedExpanded}}" hidden$="[[!hasAdvancedOrDeviceFields_(networkProperties)]]"> Advanced @@ -100,7 +105,7 @@ hidden$="[[!hasAdvancedOrDeviceFields_(networkProperties)]]"> <cr-collapse opened="[[advancedExpanded]]"> <!-- Advanced properties --> - <div id="advancedInfoDiv" class="layout vertical"> + <div id="advancedInfoDiv" class="layout vertical section"> <network-property-list fields="[[getAdvancedFields_(networkProperties)]]" property-dict="[[networkProperties]]"> @@ -108,13 +113,15 @@ </div> <!-- Network (APN, address, nameservers) --> - <div id="addressDiv" class="layout vertical" + <div id="addressDiv" class="layout vertical section" hidden$="[[!hasNetworkSection_(networkProperties)]]"> - <paper-button toggles noink active="{{addressExpanded}}"> - Network - </paper-button> + <div> + <paper-button toggles noink active="{{addressExpanded}}"> + Network + </paper-button> + </div> <cr-collapse opened="[[addressExpanded]]"> - <div class="layout vertical flex"> + <div class="layout vertical"> <network-apnlist editable hidden$="[[!isType_(networkProperties, NetworkType.CELLULAR)]]" network-properties="[[networkProperties]]" @@ -133,13 +140,15 @@ </div> <!-- Proxy --> - <div class="layout vertical" + <div class="layout vertical section" hidden$="[[!hasNetworkSection_(networkProperties)]]"> - <paper-button toggles noink active="{{proxyExpanded}}"> - Proxy - </paper-button> + <div> + <paper-button toggles noink active="{{proxyExpanded}}"> + Proxy + </paper-button> + </div> <cr-collapse opened="[[proxyExpanded]]"> - <div id="proxyDiv" class="layout vertical flex"> + <div id="proxyDiv" class="layout vertical"> <network-proxy editable network-properties="[[networkProperties]]" on-proxy-change="onProxyChange_"> @@ -149,17 +158,18 @@ </div> <!-- Device properties --> - <div class="layout vertical" + <div class="layout vertical section" hidden$="[[!hasDeviceFields_(networkProperties)]]"> - <paper-button toggles noink active="{{deviceExpanded}}"> - Device - </paper-button> + <div> + <paper-button toggles noink active="{{deviceExpanded}}"> + Device + </paper-button> + </div> <cr-collapse opened="[[deviceExpanded]]"> <network-property-list fields="[[getDeviceFields_(networkProperties)]]" property-dict="[[networkProperties]]"> </network-property-list> - <!-- TODO(stevenjb): Cellular SIM --> </cr-collapse> </div> </cr-collapse>
diff --git a/chrome/browser/resources/settings/internet_page/network_apnlist.css b/chrome/browser/resources/settings/internet_page/network_apnlist.css index 233cc8c..3f7caed 100644 --- a/chrome/browser/resources/settings/internet_page/network_apnlist.css +++ b/chrome/browser/resources/settings/internet_page/network_apnlist.css
@@ -6,9 +6,12 @@ margin-bottom: 10px; } +#selectDiv { + margin-bottom: 10px; +} + #selectDiv select { - font-size: 16px; - margin: 10px 0 10px 5px; + margin-left: 10px; padding: 5px; }
diff --git a/chrome/browser/resources/settings/internet_page/network_nameservers.css b/chrome/browser/resources/settings/internet_page/network_nameservers.css index 3dda85c..d94c3c9 100644 --- a/chrome/browser/resources/settings/internet_page/network_nameservers.css +++ b/chrome/browser/resources/settings/internet_page/network_nameservers.css
@@ -2,10 +2,11 @@ * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ +#selectTypeDiv { + margin: 10px 0; +} + select { - font-size: 16px; - margin-bottom: 10px; - margin-top: 10px; padding: 5px; }
diff --git a/chrome/browser/resources/settings/internet_page/network_nameservers.html b/chrome/browser/resources/settings/internet_page/network_nameservers.html index 3b1b6f1b..f09c1326 100644 --- a/chrome/browser/resources/settings/internet_page/network_nameservers.html +++ b/chrome/browser/resources/settings/internet_page/network_nameservers.html
@@ -6,7 +6,7 @@ <link rel="import" type="css" href="network_nameservers.css"> <template> <div id="outer" class="layout vertical"> - <div> + <div id="selectTypeDiv"> <!-- TODO(stevenjb): Use cr-dropdown-menu once available. --> <select id="type" on-change="onTypeChange_"> <template is="dom-repeat" items="[[nameserverTypeNames_]]">
diff --git a/chrome/browser/resources/settings/internet_page/network_property_list.css b/chrome/browser/resources/settings/internet_page/network_property_list.css index edad310..f63baf8 100644 --- a/chrome/browser/resources/settings/internet_page/network_property_list.css +++ b/chrome/browser/resources/settings/internet_page/network_property_list.css
@@ -3,7 +3,8 @@ * found in the LICENSE file. */ span { - margin: 0 5px 5px 0; + -webkit-margin-end: 5px; + margin-bottom: 5px; } span.fill { @@ -14,5 +15,11 @@ } paper-input-container { - margin: -8px 0 -3px 5px; + -webkit-margin-start: 5px; + margin-bottom: -3px; + margin-top: -12px; +} + +#outerDiv { + padding: 5px 0; }
diff --git a/chrome/browser/resources/settings/internet_page/network_property_list.html b/chrome/browser/resources/settings/internet_page/network_property_list.html index bc89ad75..dce7aed 100644 --- a/chrome/browser/resources/settings/internet_page/network_property_list.html +++ b/chrome/browser/resources/settings/internet_page/network_property_list.html
@@ -5,7 +5,7 @@ <dom-module name="network-property-list"> <link rel="import" type="css" href="network_property_list.css"> <template> - <div class="layout horizontal"> + <div id="outerDiv" class="layout horizontal"> <div class="layout vertical"> <template is="dom-repeat" items="[[fields]]"> <div class="layout horizontal"
diff --git a/chrome/browser/resources/settings/internet_page/network_proxy.css b/chrome/browser/resources/settings/internet_page/network_proxy.css index 0b3794a..bf734a04 100644 --- a/chrome/browser/resources/settings/internet_page/network_proxy.css +++ b/chrome/browser/resources/settings/internet_page/network_proxy.css
@@ -6,10 +6,11 @@ display: inline-block; } +#selectDiv { + margin: 10px 0; +} + select { - font-size: 16px; - margin-bottom: 10px; - margin-top: 10px; padding: 5px; }
diff --git a/chrome/browser/resources/settings/internet_page/network_proxy.html b/chrome/browser/resources/settings/internet_page/network_proxy.html index 826a535..f6a3737 100644 --- a/chrome/browser/resources/settings/internet_page/network_proxy.html +++ b/chrome/browser/resources/settings/internet_page/network_proxy.html
@@ -12,7 +12,7 @@ <template> <div id="outer" class="layout vertical flex"> <!-- TODO(stevenjb): Use cr-dropdown-menu once available. --> - <div> + <div id="selectDiv"> <select id="selectType" on-change="onTypeChange_"> <template is="dom-repeat" items="[[proxyTypes_]]"> <option value="[[item]]">[[proxyTypeDesc_(item)]]</option>
diff --git a/chrome/browser/resources/settings/internet_page/network_siminfo.css b/chrome/browser/resources/settings/internet_page/network_siminfo.css index 2f31161..df0d574 100644 --- a/chrome/browser/resources/settings/internet_page/network_siminfo.css +++ b/chrome/browser/resources/settings/internet_page/network_siminfo.css
@@ -2,16 +2,17 @@ * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ +iron-icon { + -webkit-margin-end: 5px; + -webkit-margin-start: -3px; +} + +paper-button { + margin: 0; +} + span { - margin-right: 10px; -} - -#outerDiv { - margin-bottom: 10px; -} - -#lockedDiv iron-icon { - margin: 0 5px 0 -2px; + -webkit-margin-end: 10px; } #lockedDiv span { @@ -20,16 +21,16 @@ } #lockedDiv paper-input { - margin-left: 10px; + -webkit-margin-start: 10px; width: 80px; } #unlockSimDialog paper-input { - margin-left: 5px; + -webkit-margin-start: 5px; } #unlockSimDialog span { - margin-left: 5px; + -webkit-margin-start: 5px; } .pin {
diff --git a/chrome/browser/resources/settings/internet_page/network_summary.css b/chrome/browser/resources/settings/internet_page/network_summary.css deleted file mode 100644 index 8ef2212..0000000 --- a/chrome/browser/resources/settings/internet_page/network_summary.css +++ /dev/null
@@ -1,7 +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. */ - -#summary { - padding-right: 40px; -}
diff --git a/chrome/browser/resources/settings/internet_page/network_summary.html b/chrome/browser/resources/settings/internet_page/network_summary.html index 9e3f8d7..c92c9e7 100644 --- a/chrome/browser/resources/settings/internet_page/network_summary.html +++ b/chrome/browser/resources/settings/internet_page/network_summary.html
@@ -3,7 +3,6 @@ <link rel="import" href="network_summary_item.html"> <dom-module id="network-summary"> - <link rel="import" type="css" href="network_summary.css"> <template> <div id="summary" class="layout vertical"> <network-summary-item id="ethernet"
diff --git a/chrome/browser/resources/settings/languages_page/compiled_resources.gyp b/chrome/browser/resources/settings/languages_page/compiled_resources.gyp index ea0bdf4..d62d2df 100644 --- a/chrome/browser/resources/settings/languages_page/compiled_resources.gyp +++ b/chrome/browser/resources/settings/languages_page/compiled_resources.gyp
@@ -23,7 +23,7 @@ 'target_name': 'language_detail_page', 'variables': { 'depends': [ - '../../../../../ui/webui/resources/cr_elements/v1_0/policy/cr_policy_indicator.js', + '../../../../../ui/webui/resources/cr_elements/v1_0/policy/compiled_resources.gyp:cr_policy_indicator_behavior', '../../../../../ui/webui/resources/js/chromeos/compiled_resources.gyp:ui_account_tweaks', '../../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data', '../prefs/compiled_resources.gyp:prefs',
diff --git a/chrome/browser/resources/settings/languages_page/language_detail_page.html b/chrome/browser/resources/settings/languages_page/language_detail_page.html index e3ea064..39ff9c9 100644 --- a/chrome/browser/resources/settings/languages_page/language_detail_page.html +++ b/chrome/browser/resources/settings/languages_page/language_detail_page.html
@@ -1,7 +1,7 @@ <link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-toggle-button/paper-toggle-button.html"> -<link rel="import" href="chrome://resources/cr_elements/v1_0/policy/cr_policy_indicator.html"> +<link rel="import" href="chrome://resources/cr_elements/v1_0/policy/cr_policy_pref_indicator.html"> <link rel="import" href="chrome://resources/html/assert.html"> <link rel="import" href="chrome://resources/html/cr.html"> <link rel="import" href="languages.html"> @@ -33,7 +33,8 @@ hidden$="[[!isRestartRequired_(detail.language.code, prefs.intl.app_locale.value)]]"> </paper-button> </span> - <cr-policy-indicator id="policyIndicator"></cr-policy-indicator> + <cr-policy-pref-indicator id="policyIndicator"> + </cr-policy-pref-indicator> </label> <span i18n-content="cannotBeDisplayedInThisLanguage" hidden$="[[detail.language.supportsUI]]"></span>
diff --git a/chrome/browser/resources/settings/languages_page/language_detail_page.js b/chrome/browser/resources/settings/languages_page/language_detail_page.js index b30d2a9..b3b9166 100644 --- a/chrome/browser/resources/settings/languages_page/language_detail_page.js +++ b/chrome/browser/resources/settings/languages_page/language_detail_page.js
@@ -39,7 +39,7 @@ // In a CrOS multi-user session, the primary user controls the UI language. if (this.isSecondaryUser_()) { var indicator = this.$.policyIndicator; - indicator.indicatorType = CrPolicyIndicator.Type.PRIMARY_USER; + indicator.indicatorType = CrPolicyIndicatorType.PRIMARY_USER; indicator.controllingUser = loadTimeData.getString('primaryUserEmail'); }
diff --git a/chrome/browser/resources/settings/policy_controllable/policy_controllable.html b/chrome/browser/resources/settings/policy_controllable/policy_controllable.html deleted file mode 100644 index c5a1da9..0000000 --- a/chrome/browser/resources/settings/policy_controllable/policy_controllable.html +++ /dev/null
@@ -1 +0,0 @@ -<script src="policy_controllable.js"></script>
diff --git a/chrome/browser/resources/settings/policy_controllable/policy_controllable.js b/chrome/browser/resources/settings/policy_controllable/policy_controllable.js deleted file mode 100644 index 3298d3d0..0000000 --- a/chrome/browser/resources/settings/policy_controllable/policy_controllable.js +++ /dev/null
@@ -1,20 +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. - -/** - * @fileoverview Behavior to determine whether a pref is controlled by policy. - */ - -/** @polymerBehavior */ -var PolicyControllable = { - /** - * @param {?chrome.settingsPrivate.PrefObject} pref - * @return {boolean} True if the pref is controlled by an enforced policy. - */ - isPolicyControlled: function(pref) { - return !!pref && - pref.policyEnforcement == - chrome.settingsPrivate.PolicyEnforcement.ENFORCED; - }, -};
diff --git a/chrome/browser/resources/settings/settings_resources.grd b/chrome/browser/resources/settings/settings_resources.grd index 70785765..b75cc76a 100644 --- a/chrome/browser/resources/settings/settings_resources.grd +++ b/chrome/browser/resources/settings/settings_resources.grd
@@ -253,12 +253,6 @@ <structure name="IDR_SETTINGS_LANGUAGES_LANGUAGE_DETAIL_PAGE_JS" file="languages_page/language_detail_page.js" type="chrome_html" /> - <structure name="IDR_SETTINGS_POLICY_CONTROLLABLE_HTML" - file="policy_controllable/policy_controllable.html" - type="chrome_html" /> - <structure name="IDR_SETTINGS_POLICY_CONTROLLABLE_JS" - file="policy_controllable/policy_controllable.js" - type="chrome_html" /> <structure name="IDR_SETTINGS_PREFS_HTML" file="prefs/prefs.html" type="chrome_html" /> @@ -505,9 +499,6 @@ <structure name="IDR_SETTINGS_NETWORK_SIMINFO_JS" file="internet_page/network_siminfo.js" type="chrome_html" /> - <structure name="IDR_SETTINGS_NETWORK_SUMMARY_CSS" - file="internet_page/network_summary.css" - type="chrome_html" /> <structure name="IDR_SETTINGS_NETWORK_SUMMARY_HTML" file="internet_page/network_summary.html" type="chrome_html" />
diff --git a/chrome/browser/stack_sampling_configuration.cc b/chrome/browser/stack_sampling_configuration.cc index 63e1305d..51d6280 100644 --- a/chrome/browser/stack_sampling_configuration.cc +++ b/chrome/browser/stack_sampling_configuration.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/stack_sampling_configuration.h" +#include "base/rand_util.h" #include "chrome/browser/metrics/chrome_metrics_service_accessor.h" #include "chrome/common/channel_info.h" #include "components/version_info/version_info.h" @@ -20,8 +21,7 @@ } // namespace StackSamplingConfiguration::StackSamplingConfiguration() - // Disabled pending fixes for deadlock scenarios. https://crbug.com/528129. - : configuration_(PROFILE_DISABLED) { + : configuration_(GenerateConfiguration()) { } base::StackSamplingProfiler::SamplingParams @@ -32,6 +32,7 @@ switch (configuration_) { case PROFILE_DISABLED: + case PROFILE_CONTROL: params.initial_delay = base::TimeDelta::FromMilliseconds(0); params.sampling_interval = base::TimeDelta::FromMilliseconds(0); params.samples_per_burst = 0; @@ -79,6 +80,10 @@ group = "Disabled"; break; + case PROFILE_CONTROL: + group = "Control"; + break; + case PROFILE_NO_SAMPLES: group = "NoSamples"; break; @@ -100,3 +105,41 @@ "SyntheticStackProfilingConfiguration", group); } + +// static +StackSamplingConfiguration::ProfileConfiguration +StackSamplingConfiguration::GenerateConfiguration() { + // Enable the profiler in the intended ultimate production configuration for + // development/waterfall builds. + if (chrome::GetChannel() == version_info::Channel::UNKNOWN) + return PROFILE_10HZ; + + struct Variation { + ProfileConfiguration config; + int weight; + }; + + // Generate a configuration according to the associated weights. + const Variation variations[] = { + { PROFILE_10HZ, 15}, + { PROFILE_CONTROL, 15}, + { PROFILE_DISABLED, 70} + }; + + int total_weight = 0; + for (const Variation& variation : variations) + total_weight += variation.weight; + DCHECK_EQ(100, total_weight); + + int chosen = base::RandInt(0, total_weight - 1); // Max is inclusive. + int cumulative_weight = 0; + for (const Variation& variation : variations) { + if (chosen >= cumulative_weight && + chosen < cumulative_weight + variation.weight) { + return variation.config; + } + cumulative_weight += variation.weight; + } + NOTREACHED(); + return PROFILE_DISABLED; +}
diff --git a/chrome/browser/stack_sampling_configuration.h b/chrome/browser/stack_sampling_configuration.h index e8c32fcf..9d18aa80 100644 --- a/chrome/browser/stack_sampling_configuration.h +++ b/chrome/browser/stack_sampling_configuration.h
@@ -26,13 +26,15 @@ private: enum ProfileConfiguration { PROFILE_DISABLED, + PROFILE_CONTROL, PROFILE_NO_SAMPLES, // Run the profiler thread, but don't collect profiles. PROFILE_5HZ, PROFILE_10HZ, - PROFILE_100HZ, - PROFILE_COUNT = PROFILE_100HZ + PROFILE_100HZ }; + static ProfileConfiguration GenerateConfiguration(); + const ProfileConfiguration configuration_; DISALLOW_COPY_AND_ASSIGN(StackSamplingConfiguration);
diff --git a/chrome/browser/ui/browser_dialogs_mac.cc b/chrome/browser/ui/browser_dialogs_mac.cc index 1d67a32..cf79ad9 100644 --- a/chrome/browser/ui/browser_dialogs_mac.cc +++ b/chrome/browser/ui/browser_dialogs_mac.cc
@@ -5,7 +5,7 @@ #include "chrome/browser/ui/browser_dialogs.h" #include "base/command_line.h" -#include "chrome/common/chrome_switches.cc" +#include "chrome/common/chrome_switches.h" namespace chrome {
diff --git a/chrome/browser/ui/browser_tabstrip.cc b/chrome/browser/ui/browser_tabstrip.cc index 995e0de..93f4a7bb 100644 --- a/chrome/browser/ui/browser_tabstrip.cc +++ b/chrome/browser/ui/browser_tabstrip.cc
@@ -24,9 +24,10 @@ // WebContents, but we want to include the time it takes to create the // WebContents object too. base::TimeTicks new_tab_start_time = base::TimeTicks::Now(); + bool show_ntp = url.is_empty(); chrome::NavigateParams params(browser, - url.is_empty() ? GURL(chrome::kChromeUINewTabURL) : url, - ui::PAGE_TRANSITION_TYPED); + show_ntp ? GURL(chrome::kChromeUINewTabURL) : url, + show_ntp ? ui::PAGE_TRANSITION_AUTO_TOPLEVEL : ui::PAGE_TRANSITION_TYPED); params.disposition = foreground ? NEW_FOREGROUND_TAB : NEW_BACKGROUND_TAB; params.tabstrip_index = idx; chrome::Navigate(¶ms);
diff --git a/chrome/browser/ui/content_settings/content_setting_image_model.cc b/chrome/browser/ui/content_settings/content_setting_image_model.cc index 94a2e08..d2099c8d 100644 --- a/chrome/browser/ui/content_settings/content_setting_image_model.cc +++ b/chrome/browser/ui/content_settings/content_setting_image_model.cc
@@ -15,11 +15,11 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/material_design/material_design_controller.h" #include "ui/base/resource/resource_bundle.h" +#include "ui/gfx/vector_icons_public.h" #if !defined(OS_MACOSX) #include "ui/gfx/color_palette.h" #include "ui/gfx/paint_vector_icon.h" -#include "ui/gfx/vector_icons_public.h" #endif using content::WebContents; @@ -90,19 +90,81 @@ namespace { -struct ContentSettingsTypeIdEntry { +struct ContentSettingsImageDetails { ContentSettingsType type; - int id; + int blocked_icon_id; + gfx::VectorIconId vector_icon_id; + int blocked_tooltip_id; + int blocked_explanatory_text_id; + int accessed_icon_id; + int accessed_tooltip_id; }; -int GetIdForContentType(const ContentSettingsTypeIdEntry* entries, - size_t num_entries, - ContentSettingsType type) { - for (size_t i = 0; i < num_entries; ++i) { - if (entries[i].type == type) - return entries[i].id; +static const ContentSettingsImageDetails kImageDetails[] = { + {CONTENT_SETTINGS_TYPE_COOKIES, + IDR_BLOCKED_COOKIES, + gfx::VectorIconId::COOKIE, + IDS_BLOCKED_COOKIES_TITLE, + 0, + IDR_ACCESSED_COOKIES, + IDS_ACCESSED_COOKIES_TITLE}, + {CONTENT_SETTINGS_TYPE_IMAGES, + IDR_BLOCKED_IMAGES, + gfx::VectorIconId::IMAGE, + IDS_BLOCKED_IMAGES_TITLE, + 0, + 0, + 0}, + {CONTENT_SETTINGS_TYPE_JAVASCRIPT, + IDR_BLOCKED_JAVASCRIPT, + gfx::VectorIconId::CODE, + IDS_BLOCKED_JAVASCRIPT_TITLE, + 0, + 0, + 0}, + {CONTENT_SETTINGS_TYPE_PLUGINS, + IDR_BLOCKED_PLUGINS, + gfx::VectorIconId::EXTENSION, + IDS_BLOCKED_PLUGINS_MESSAGE, + IDS_BLOCKED_PLUGIN_EXPLANATORY_TEXT, + 0, + 0}, + {CONTENT_SETTINGS_TYPE_POPUPS, + IDR_BLOCKED_POPUPS, + gfx::VectorIconId::WEB, + IDS_BLOCKED_POPUPS_TOOLTIP, + IDS_BLOCKED_POPUPS_EXPLANATORY_TEXT, + 0, + 0}, + {CONTENT_SETTINGS_TYPE_MIXEDSCRIPT, + IDR_BLOCKED_MIXED_CONTENT, + gfx::VectorIconId::MIXED_CONTENT, + IDS_BLOCKED_DISPLAYING_INSECURE_CONTENT, + 0, + 0, + 0}, + {CONTENT_SETTINGS_TYPE_PPAPI_BROKER, + IDR_BLOCKED_PPAPI_BROKER, + gfx::VectorIconId::EXTENSION, + IDS_BLOCKED_PPAPI_BROKER_TITLE, + 0, + IDR_BLOCKED_PPAPI_BROKER, + IDS_ALLOWED_PPAPI_BROKER_TITLE}, + {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, + IDR_BLOCKED_DOWNLOADS, + gfx::VectorIconId::FILE_DOWNLOAD, + IDS_BLOCKED_DOWNLOAD_TITLE, + IDS_BLOCKED_DOWNLOADS_EXPLANATION, + IDR_ALLOWED_DOWNLOADS, + IDS_ALLOWED_DOWNLOAD_TITLE}, +}; + +const ContentSettingsImageDetails* GetImageDetails(ContentSettingsType type) { + for (const ContentSettingsImageDetails& image_details : kImageDetails) { + if (image_details.type == type) + return &image_details; } - return 0; + return nullptr; } } // namespace @@ -119,76 +181,11 @@ return; ContentSettingsType type = get_content_settings_type(); - static const ContentSettingsTypeIdEntry kBlockedIconIDs[] = { - {CONTENT_SETTINGS_TYPE_COOKIES, IDR_BLOCKED_COOKIES}, - {CONTENT_SETTINGS_TYPE_IMAGES, IDR_BLOCKED_IMAGES}, - {CONTENT_SETTINGS_TYPE_JAVASCRIPT, IDR_BLOCKED_JAVASCRIPT}, - {CONTENT_SETTINGS_TYPE_PLUGINS, IDR_BLOCKED_PLUGINS}, - {CONTENT_SETTINGS_TYPE_POPUPS, IDR_BLOCKED_POPUPS}, - {CONTENT_SETTINGS_TYPE_MIXEDSCRIPT, IDR_BLOCKED_MIXED_CONTENT}, - {CONTENT_SETTINGS_TYPE_PPAPI_BROKER, IDR_BLOCKED_PPAPI_BROKER}, - {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, IDR_BLOCKED_DOWNLOADS}, - }; - int icon_id = - GetIdForContentType(kBlockedIconIDs, arraysize(kBlockedIconIDs), type); + const ContentSettingsImageDetails* image_details = GetImageDetails(type); -#if !defined(OS_MACOSX) - gfx::VectorIconId vector_icon_id = gfx::VectorIconId::VECTOR_ICON_NONE; - switch (type) { - case CONTENT_SETTINGS_TYPE_COOKIES: - vector_icon_id = gfx::VectorIconId::COOKIE; - break; - case CONTENT_SETTINGS_TYPE_IMAGES: - vector_icon_id = gfx::VectorIconId::IMAGE; - break; - case CONTENT_SETTINGS_TYPE_JAVASCRIPT: - vector_icon_id = gfx::VectorIconId::CODE; - break; - case CONTENT_SETTINGS_TYPE_PLUGINS: - vector_icon_id = gfx::VectorIconId::EXTENSION; - break; - case CONTENT_SETTINGS_TYPE_POPUPS: - vector_icon_id = gfx::VectorIconId::WEB; - break; - case CONTENT_SETTINGS_TYPE_MIXEDSCRIPT: - vector_icon_id = gfx::VectorIconId::MIXED_CONTENT; - break; - case CONTENT_SETTINGS_TYPE_PPAPI_BROKER: - vector_icon_id = gfx::VectorIconId::EXTENSION; - break; - case CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS: - vector_icon_id = gfx::VectorIconId::FILE_DOWNLOAD; - break; - default: - // If we didn't find a vector icon ID we shouldn't have found an - // asset ID either. - DCHECK_EQ(0, icon_id); - break; - } -#endif - - static const ContentSettingsTypeIdEntry kBlockedTooltipIDs[] = { - {CONTENT_SETTINGS_TYPE_COOKIES, IDS_BLOCKED_COOKIES_TITLE}, - {CONTENT_SETTINGS_TYPE_IMAGES, IDS_BLOCKED_IMAGES_TITLE}, - {CONTENT_SETTINGS_TYPE_JAVASCRIPT, IDS_BLOCKED_JAVASCRIPT_TITLE}, - {CONTENT_SETTINGS_TYPE_PLUGINS, IDS_BLOCKED_PLUGINS_MESSAGE}, - {CONTENT_SETTINGS_TYPE_POPUPS, IDS_BLOCKED_POPUPS_TOOLTIP}, - {CONTENT_SETTINGS_TYPE_MIXEDSCRIPT, - IDS_BLOCKED_DISPLAYING_INSECURE_CONTENT}, - {CONTENT_SETTINGS_TYPE_PPAPI_BROKER, IDS_BLOCKED_PPAPI_BROKER_TITLE}, - {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, IDS_BLOCKED_DOWNLOAD_TITLE}, - }; - int tooltip_id = GetIdForContentType(kBlockedTooltipIDs, - arraysize(kBlockedTooltipIDs), type); - - static const ContentSettingsTypeIdEntry kBlockedExplanatoryTextIDs[] = { - {CONTENT_SETTINGS_TYPE_POPUPS, IDS_BLOCKED_POPUPS_EXPLANATORY_TEXT}, - {CONTENT_SETTINGS_TYPE_PLUGINS, IDS_BLOCKED_PLUGIN_EXPLANATORY_TEXT}, - {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, - IDS_BLOCKED_DOWNLOADS_EXPLANATION}, - }; - int explanation_id = GetIdForContentType( - kBlockedExplanatoryTextIDs, arraysize(kBlockedExplanatoryTextIDs), type); + int icon_id = image_details->blocked_icon_id; + int tooltip_id = image_details->blocked_tooltip_id; + int explanation_id = image_details->blocked_explanatory_text_id; // For plugins, don't show the animated explanation unless the plugin was // blocked despite the user's content settings being set to allow it (e.g. @@ -220,20 +217,8 @@ (map->GetDefaultContentSetting(type, NULL) != CONTENT_SETTING_BLOCK)) return; - static const ContentSettingsTypeIdEntry kAccessedIconIDs[] = { - {CONTENT_SETTINGS_TYPE_COOKIES, IDR_ACCESSED_COOKIES}, - {CONTENT_SETTINGS_TYPE_PPAPI_BROKER, IDR_BLOCKED_PPAPI_BROKER}, - {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, IDR_ALLOWED_DOWNLOADS}, - }; - icon_id = GetIdForContentType(kAccessedIconIDs, arraysize(kAccessedIconIDs), - type); - static const ContentSettingsTypeIdEntry kAccessedTooltipIDs[] = { - {CONTENT_SETTINGS_TYPE_COOKIES, IDS_ACCESSED_COOKIES_TITLE}, - {CONTENT_SETTINGS_TYPE_PPAPI_BROKER, IDS_ALLOWED_PPAPI_BROKER_TITLE}, - {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, IDS_ALLOWED_DOWNLOAD_TITLE}, - }; - tooltip_id = GetIdForContentType( - kAccessedTooltipIDs, arraysize(kAccessedTooltipIDs), type); + icon_id = image_details->accessed_icon_id; + tooltip_id = image_details->accessed_tooltip_id; explanation_id = 0; } set_visible(true); @@ -242,12 +227,11 @@ SetIconByResourceId(icon_id); #if !defined(OS_MACOSX) } else { - DCHECK(gfx::VectorIconId::VECTOR_ICON_NONE != vector_icon_id); - if (type == CONTENT_SETTINGS_TYPE_PPAPI_BROKER) { - set_icon(GetIcon(vector_icon_id, gfx::VectorIconId::WARNING_BADGE)); + set_icon(GetIcon(image_details->vector_icon_id, + gfx::VectorIconId::WARNING_BADGE)); } else { - SetIconByVectorId(vector_icon_id, + SetIconByVectorId(image_details->vector_icon_id, content_settings->IsContentBlocked(type)); } #endif @@ -452,21 +436,18 @@ ContentSettingImageModel* ContentSettingImageModel::CreateContentSettingImageModel( ContentSettingsType content_settings_type) { - switch (content_settings_type) { - case CONTENT_SETTINGS_TYPE_GEOLOCATION: - return new ContentSettingGeolocationImageModel(); - case CONTENT_SETTINGS_TYPE_NOTIFICATIONS: - return new ContentSettingNotificationsImageModel(); - case CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS: - return new ContentSettingRPHImageModel(); - case CONTENT_SETTINGS_TYPE_MEDIASTREAM: - case CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC: - case CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA: - return new ContentSettingMediaImageModel(content_settings_type); - case CONTENT_SETTINGS_TYPE_MIDI_SYSEX: - return new ContentSettingMIDISysExImageModel(); - default: - return new ContentSettingBlockedImageModel(content_settings_type); + if (content_settings_type == CONTENT_SETTINGS_TYPE_GEOLOCATION) { + return new ContentSettingGeolocationImageModel(); + } else if (content_settings_type == CONTENT_SETTINGS_TYPE_NOTIFICATIONS) { + return new ContentSettingNotificationsImageModel(); + } else if (content_settings_type == CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS) { + return new ContentSettingRPHImageModel(); + } else if (content_settings_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM) { + return new ContentSettingMediaImageModel(content_settings_type); + } else if (content_settings_type == CONTENT_SETTINGS_TYPE_MIDI_SYSEX) { + return new ContentSettingMIDISysExImageModel(); + } else { + return new ContentSettingBlockedImageModel(content_settings_type); } }
diff --git a/chrome/browser/ui/libgtk2ui/gtk2_ui.cc b/chrome/browser/ui/libgtk2ui/gtk2_ui.cc index 3e20da3..07b76f3 100644 --- a/chrome/browser/ui/libgtk2ui/gtk2_ui.cc +++ b/chrome/browser/ui/libgtk2ui/gtk2_ui.cc
@@ -1013,12 +1013,9 @@ active_selection_fg_color_ = theme->GetSystemColor( ui::NativeTheme::kColorId_TextfieldSelectionColor); - inactive_selection_bg_color_ = - theme->GetSystemColor( - ui::NativeTheme::kColorId_TextfieldReadOnlyBackground); - inactive_selection_fg_color_ = - theme->GetSystemColor( - ui::NativeTheme::kColorId_TextfieldReadOnlyColor); + + inactive_selection_bg_color_ = active_selection_bg_color_; + inactive_selection_fg_color_ = active_selection_fg_color_; colors_[ThemeProperties::COLOR_THROBBER_SPINNING] = theme->GetSystemColor(ui::NativeTheme::kColorId_ThrobberSpinningColor);
diff --git a/chrome/browser/ui/navigation_correction_tab_observer.cc b/chrome/browser/ui/navigation_correction_tab_observer.cc index 6be6a9f..a943d401 100644 --- a/chrome/browser/ui/navigation_correction_tab_observer.cc +++ b/chrome/browser/ui/navigation_correction_tab_observer.cc
@@ -15,12 +15,10 @@ #include "components/google/core/browser/google_util.h" #include "components/pref_registry/pref_registry_syncable.h" #include "content/public/browser/render_frame_host.h" -#include "content/public/browser/render_view_host.h" #include "content/public/browser/web_contents.h" #include "google_apis/google_api_keys.h" using content::RenderFrameHost; -using content::RenderViewHost; using content::WebContents; DEFINE_WEB_CONTENTS_USER_DATA_KEY(NavigationCorrectionTabObserver); @@ -65,16 +63,20 @@ //////////////////////////////////////////////////////////////////////////////// // WebContentsObserver overrides -void NavigationCorrectionTabObserver::RenderViewCreated( - RenderViewHost* render_view_host) { - UpdateNavigationCorrectionInfo(render_view_host); +void NavigationCorrectionTabObserver::RenderFrameCreated( + RenderFrameHost* render_frame_host) { + // Ignore subframe creation - only main frame error pages can request and + // display nagivation correction information. + if (render_frame_host->GetParent()) + return; + UpdateNavigationCorrectionInfo(render_frame_host); } //////////////////////////////////////////////////////////////////////////////// // Internal helpers void NavigationCorrectionTabObserver::OnGoogleURLUpdated() { - UpdateNavigationCorrectionInfo(web_contents()->GetRenderViewHost()); + UpdateNavigationCorrectionInfo(web_contents()->GetMainFrame()); } GURL NavigationCorrectionTabObserver::GetNavigationCorrectionURL() const { @@ -89,15 +91,14 @@ } void NavigationCorrectionTabObserver::OnEnabledChanged() { - UpdateNavigationCorrectionInfo(web_contents()->GetRenderViewHost()); + UpdateNavigationCorrectionInfo(web_contents()->GetMainFrame()); } void NavigationCorrectionTabObserver::UpdateNavigationCorrectionInfo( - RenderViewHost* rvh) { - RenderFrameHost* rfh = rvh->GetMainFrame(); + RenderFrameHost* render_frame_host) { GURL google_base_url(UIThreadSearchTermsData(profile_).GoogleBaseURLValue()); - rfh->Send(new ChromeViewMsg_SetNavigationCorrectionInfo( - rfh->GetRoutingID(), + render_frame_host->Send(new ChromeViewMsg_SetNavigationCorrectionInfo( + render_frame_host->GetRoutingID(), GetNavigationCorrectionURL(), google_util::GetGoogleLocale(g_browser_process->GetApplicationLocale()), google_util::GetGoogleCountryCode(google_base_url),
diff --git a/chrome/browser/ui/navigation_correction_tab_observer.h b/chrome/browser/ui/navigation_correction_tab_observer.h index 85a2095..cc562f9 100644 --- a/chrome/browser/ui/navigation_correction_tab_observer.h +++ b/chrome/browser/ui/navigation_correction_tab_observer.h
@@ -30,7 +30,7 @@ friend class content::WebContentsUserData<NavigationCorrectionTabObserver>; // content::WebContentsObserver overrides: - void RenderViewCreated(content::RenderViewHost* render_view_host) override; + void RenderFrameCreated(content::RenderFrameHost* render_frame_host) override; // Internal helpers ---------------------------------------------------------- @@ -45,7 +45,8 @@ void OnEnabledChanged(); // Updates the renderer's navigation correction service configuration. - void UpdateNavigationCorrectionInfo(content::RenderViewHost* rvh); + void UpdateNavigationCorrectionInfo( + content::RenderFrameHost* render_frame_host); Profile* profile_; PrefChangeRegistrar pref_change_registrar_;
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc index 50c520c8..d354428c 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc
@@ -74,12 +74,14 @@ #include "ui/base/dragdrop/os_exchange_data.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/page_transition_types.h" +#include "ui/base/resource/material_design/material_design_controller.h" #include "ui/base/resource/resource_bundle.h" #include "ui/base/theme_provider.h" #include "ui/base/window_open_disposition.h" #include "ui/compositor/paint_recorder.h" #include "ui/gfx/animation/slide_animation.h" #include "ui/gfx/canvas.h" +#include "ui/gfx/favicon_size.h" #include "ui/gfx/paint_vector_icon.h" #include "ui/gfx/text_constants.h" #include "ui/gfx/text_elider.h" @@ -145,8 +147,8 @@ static const int kSeparatorMargin = 1; // Width of the separator between the recently bookmarked button and the -// overflow indicator. -static const int kSeparatorWidth = 4; +// overflow indicator, indexed by MD mode. +static const int kSeparatorWidth[] = {4, 9, 9}; // Starting x-coordinate of the separator line within a separator. static const int kSeparatorStartX = 2; @@ -347,8 +349,7 @@ class OverflowButton : public views::MenuButton { public: explicit OverflowButton(BookmarkBarView* owner) - : MenuButton(NULL, base::string16(), owner, false), - owner_(owner) {} + : MenuButton(NULL, base::string16(), owner, false), owner_(owner) {} bool OnMousePressed(const ui::MouseEvent& e) override { owner_->StopThrobbing(true); @@ -475,20 +476,40 @@ ~ButtonSeparatorView() override {} void OnPaint(gfx::Canvas* canvas) override { - PaintVerticalDivider( - canvas, - kSeparatorStartX, - height(), - 1, - kEdgeDividerColor, - kMiddleDividerColor, - GetThemeProvider()->GetColor(ThemeProperties::COLOR_TOOLBAR)); + if (ui::MaterialDesignController::IsModeMaterial()) { + // 1px wide at all scale factors. If there is an uneven amount of padding + // left over, place the extra pixel on the outside, i.e. away from the + // "Other bookmarks" folder. + const float scale = canvas->SaveAndUnscale(); + const gfx::RectF scaled_bounds = + gfx::ScaleRect(gfx::RectF(bounds()), scale); + + const int kLineThickness = 1; + const float fractional_x = (scaled_bounds.width() - kLineThickness) / 2.f; + const int x = base::i18n::IsRTL() ? std::floor(fractional_x) + : std::ceil(fractional_x); + + const int height = gfx::kFaviconSize * scale; + const int top_y = (scaled_bounds.height() - height) / 2; + canvas->DrawLine( + gfx::Point(x, top_y), gfx::Point(x, top_y + height), + SkColorSetA(GetThemeProvider()->GetColor( + ThemeProperties::COLOR_TOOLBAR_BUTTON_ICON), + 0x4D)); + canvas->Restore(); + } else { + PaintVerticalDivider( + canvas, kSeparatorStartX, height(), 1, kEdgeDividerColor, + kMiddleDividerColor, + GetThemeProvider()->GetColor(ThemeProperties::COLOR_TOOLBAR)); + } } gfx::Size GetPreferredSize() const override { // We get the full height of the bookmark bar, so that the height returned // here doesn't matter. - return gfx::Size(kSeparatorWidth, 1); + return gfx::Size(kSeparatorWidth[ui::MaterialDesignController::GetMode()], + 1); } void GetAccessibleState(ui::AXViewState* state) override {
diff --git a/chrome/browser/ui/views/toolbar/toolbar_action_view.cc b/chrome/browser/ui/views/toolbar/toolbar_action_view.cc index 95ce226..3e142b44 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_action_view.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_action_view.cc
@@ -6,7 +6,6 @@ #include <string> -#include "base/auto_reset.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/sessions/session_tab_helper.h" @@ -28,7 +27,6 @@ #include "ui/resources/grit/ui_resources.h" #include "ui/views/controls/button/label_button_border.h" #include "ui/views/controls/menu/menu_controller.h" -#include "ui/views/controls/menu/menu_model_adapter.h" #include "ui/views/controls/menu/menu_runner.h" #include "ui/views/mouse_constants.h" #include "ui/views/resources/grit/views_resources.h" @@ -47,9 +45,6 @@ // safe to have this be a global singleton. ToolbarActionView* context_menu_owner = nullptr; -// The callback to call directly before showing the context menu. -ToolbarActionView::ContextMenuCallback* context_menu_callback = nullptr; - } // namespace //////////////////////////////////////////////////////////////////////////////// @@ -65,7 +60,6 @@ delegate_(delegate), called_register_command_(false), wants_to_run_(false), - menu_(nullptr), weak_factory_(this) { set_id(VIEW_ID_BROWSER_ACTION); view_controller_->SetDelegate(this); @@ -199,11 +193,6 @@ return GetImage(views::Button::STATE_NORMAL); } -void ToolbarActionView::set_context_menu_callback_for_testing( - base::Callback<void(ToolbarActionView*)>* callback) { - context_menu_callback = callback; -} - views::View* ToolbarActionView::GetAsView() { return this; } @@ -220,7 +209,7 @@ } bool ToolbarActionView::IsMenuRunning() const { - return menu_ != nullptr; + return menu_runner_.get() != nullptr; } content::WebContents* ToolbarActionView::GetCurrentWebContents() const { @@ -280,6 +269,7 @@ DCHECK(visible()); // We should never show a context menu for a hidden item. DCHECK(!context_menu_owner); + context_menu_owner = this; gfx::Point screen_loc; ConvertPointToScreen(this, &screen_loc); @@ -295,25 +285,18 @@ delegate_->GetOverflowReferenceView()->GetWidget() : GetWidget(); - views::MenuModelAdapter adapter(context_menu_model); - views::MenuItemView* menu_root = adapter.CreateMenu(); + menu_runner_.reset(new views::MenuRunner(context_menu_model, run_types)); - { - base::AutoReset<views::MenuItemView*> menu_resetter(&menu_, menu_root); - base::AutoReset<ToolbarActionView*> menu_owner_resetter(&context_menu_owner, - this); - - views::MenuRunner menu_runner(menu_, run_types); - - if (context_menu_callback) - context_menu_callback->Run(this); - if (menu_runner.RunMenuAt(parent, this, gfx::Rect(screen_loc, size()), + if (menu_runner_->RunMenuAt(parent, + this, + gfx::Rect(screen_loc, size()), views::MENU_ANCHOR_TOPLEFT, source_type) == views::MenuRunner::MENU_DELETED) { - return; - } + return; } + context_menu_owner = nullptr; + menu_runner_.reset(); view_controller_->OnContextMenuClosed(); // If another extension action wants to show its context menu, allow it to.
diff --git a/chrome/browser/ui/views/toolbar/toolbar_action_view.h b/chrome/browser/ui/views/toolbar/toolbar_action_view.h index 8555af7..19db601bd 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_action_view.h +++ b/chrome/browser/ui/views/toolbar/toolbar_action_view.h
@@ -5,7 +5,6 @@ #ifndef CHROME_BROWSER_UI_VIEWS_TOOLBAR_TOOLBAR_ACTION_VIEW_H_ #define CHROME_BROWSER_UI_VIEWS_TOOLBAR_TOOLBAR_ACTION_VIEW_H_ -#include "base/callback.h" #include "chrome/browser/ui/views/toolbar/toolbar_action_view_delegate_views.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" @@ -27,7 +26,7 @@ } namespace views { -class MenuItemView; +class MenuRunner; } //////////////////////////////////////////////////////////////////////////////// @@ -99,14 +98,6 @@ bool wants_to_run_for_testing() const { return wants_to_run_; } - using ContextMenuCallback = base::Callback<void(ToolbarActionView*)>; - // Set a callback to be called directly before the context menu is shown. - // The toolbar action opening the menu will be passed in. - static void set_context_menu_callback_for_testing( - ContextMenuCallback* callback); - - views::MenuItemView* menu_for_testing() { return menu_; } - private: // views::MenuButton: gfx::Size GetPreferredSize() const override; @@ -155,9 +146,8 @@ // tab. bool wants_to_run_; - // The root MenuItemView for the context menu, or null if no menu is being - // shown. - views::MenuItemView* menu_; + // Responsible for running the menu. + scoped_ptr<views::MenuRunner> menu_runner_; // If non-null, this is the next toolbar action context menu that wants to run // once the current owner (this one) is done.
diff --git a/chrome/browser/ui/views/toolbar/toolbar_action_view_interactive_uitest.cc b/chrome/browser/ui/views/toolbar/toolbar_action_view_interactive_uitest.cc index 56d34ce0..c91b0f1 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_action_view_interactive_uitest.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_action_view_interactive_uitest.cc
@@ -3,12 +3,8 @@ // found in the LICENSE file. #include "base/run_loop.h" -#include "base/strings/string_number_conversions.h" -#include "chrome/browser/extensions/extension_action_test_util.h" #include "chrome/browser/extensions/extension_browsertest.h" -#include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/ui/extensions/extension_action_view_controller.h" -#include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/toolbar/toolbar_action_view_controller.h" #include "chrome/browser/ui/toolbar/toolbar_actions_bar.h" #include "chrome/browser/ui/views/frame/browser_view.h" @@ -21,26 +17,18 @@ #include "chrome/test/base/interactive_test_utils.h" #include "extensions/common/feature_switch.h" #include "extensions/test/extension_test_message_listener.h" -#include "ui/views/controls/menu/menu_controller.h" -#include "ui/views/controls/menu/menu_item_view.h" -#include "ui/views/controls/menu/submenu_view.h" namespace { -WrenchToolbarButton* GetWrenchButtonFromBrowser(Browser* browser) { - return BrowserView::GetBrowserViewForBrowser(browser) - ->toolbar() - ->app_menu_button(); -} - // Tests clicking on an overflowed toolbar action. This is called when the app // menu is open, and handles actually clicking on the action. -// |button| specifies the mouse button to click with. void TestOverflowedToolbarAction(Browser* browser, - ui_controls::MouseButton button, const base::Closure& quit_closure) { // A bunch of plumbing to safely get at the overflowed toolbar action. - WrenchToolbarButton* app_menu_button = GetWrenchButtonFromBrowser(browser); + WrenchToolbarButton* app_menu_button = + BrowserView::GetBrowserViewForBrowser(browser) + ->toolbar() + ->app_menu_button(); EXPECT_TRUE(app_menu_button->IsMenuShowing()); WrenchMenu* app_menu = app_menu_button->app_menu_for_testing(); ASSERT_TRUE(app_menu); @@ -54,81 +42,12 @@ overflow_container->GetToolbarActionViewAt(0); EXPECT_TRUE(action_view->visible()); - // Click on the toolbar action to activate it. + // Left click on the toolbar action to activate it. gfx::Point action_view_loc = test::GetCenterInScreenCoordinates(action_view); ui_controls::SendMouseMove(action_view_loc.x(), action_view_loc.y()); ui_controls::SendMouseEventsNotifyWhenDone( - button, ui_controls::DOWN | ui_controls::UP, quit_closure); -} - -// Tests the context menu of an overflowed action. -void TestWhileContextMenuOpen(bool* did_test_while_menu_open, - Browser* browser, - ToolbarActionView* context_menu_action) { - *did_test_while_menu_open = true; - - views::MenuItemView* menu_root = context_menu_action->menu_for_testing(); - ASSERT_TRUE(menu_root); - ASSERT_TRUE(menu_root->GetSubmenu()); - EXPECT_TRUE(menu_root->GetSubmenu()->IsShowing()); - views::MenuItemView* first_menu_item = - menu_root->GetSubmenu()->GetMenuItemAt(0); - ASSERT_TRUE(first_menu_item); - - // Make sure we're showing the right context menu. - EXPECT_EQ(base::UTF8ToUTF16("Browser Action Popup"), - first_menu_item->title()); - EXPECT_TRUE(first_menu_item->enabled()); - - // Get the overflow container. - WrenchToolbarButton* app_menu_button = GetWrenchButtonFromBrowser(browser); - WrenchMenu* app_menu = app_menu_button->app_menu_for_testing(); - ASSERT_TRUE(app_menu); - ExtensionToolbarMenuView* menu_view = - app_menu->extension_toolbar_for_testing(); - ASSERT_TRUE(menu_view); - BrowserActionsContainer* overflow_container = - menu_view->container_for_testing(); - ASSERT_TRUE(overflow_container); - - // Get the first action on the second row of the overflow container. - int second_row_index = overflow_container->toolbar_actions_bar() - ->platform_settings() - .icons_per_overflow_menu_row; - ToolbarActionView* second_row_action = - overflow_container->GetToolbarActionViewAt(second_row_index); - - EXPECT_TRUE(second_row_action->visible()); - EXPECT_TRUE(second_row_action->enabled()); - - gfx::Point action_view_loc = - test::GetCenterInScreenCoordinates(second_row_action); - gfx::Point action_view_loc_in_menu_item_bounds = action_view_loc; - views::View::ConvertPointFromScreen(first_menu_item, - &action_view_loc_in_menu_item_bounds); - // Regression test for crbug.com/538414: The first menu item is overlapping - // the second row action button. With crbug.com/538414, the click would go to - // the menu button, instead of the menu item. - EXPECT_TRUE( - first_menu_item->HitTestPoint(action_view_loc_in_menu_item_bounds)); - - // Click on the first menu item (which shares bounds, but overlaps, the second - // row action). - ui_controls::SendMouseMove(action_view_loc.x(), action_view_loc.y()); - ui_controls::SendMouseEventsNotifyWhenDone( - ui_controls::LEFT, ui_controls::DOWN | ui_controls::UP, base::Closure()); - - // Test resumes in the main test body. -} - -// Posts a task to test the context menu. -void OnContextMenuWillShow(bool* did_test_while_menu_open, - Browser* browser, - ToolbarActionView* toolbar_action_view) { - base::MessageLoop::current()->task_runner()->PostTask( - FROM_HERE, base::Bind(&TestWhileContextMenuOpen, did_test_while_menu_open, - browser, toolbar_action_view)); + ui_controls::LEFT, ui_controls::DOWN | ui_controls::UP, quit_closure); } } // namespace @@ -187,7 +106,10 @@ // opened. Listen for the message. ExtensionTestMessageListener listener("Popup opened", false); - WrenchToolbarButton* app_menu_button = GetWrenchButtonFromBrowser(browser()); + WrenchToolbarButton* app_menu_button = + BrowserView::GetBrowserViewForBrowser(browser()) + ->toolbar() + ->app_menu_button(); // Click on the app button. gfx::Point app_button_loc = @@ -195,9 +117,9 @@ base::RunLoop loop; ui_controls::SendMouseMove(app_button_loc.x(), app_button_loc.y()); ui_controls::SendMouseEventsNotifyWhenDone( - ui_controls::LEFT, ui_controls::DOWN | ui_controls::UP, - base::Bind(&TestOverflowedToolbarAction, browser(), ui_controls::LEFT, - loop.QuitClosure())); + ui_controls::LEFT, + ui_controls::DOWN | ui_controls::UP, + base::Bind(&TestOverflowedToolbarAction, browser(), loop.QuitClosure())); loop.Run(); // The app menu should no longer be showing. EXPECT_FALSE(app_menu_button->IsMenuShowing()); @@ -206,76 +128,6 @@ listener.WaitUntilSatisfied(); } -#if defined(USE_OZONE) -// ozone bringup - http://crbug.com/401304 -#define MAYBE_TestContextMenuOnOverflowedAction \ - DISABLED_TestContextMenuOnOverflowedAction -#else -#define MAYBE_TestContextMenuOnOverflowedAction \ - TestContextMenuOnOverflowedAction -#endif -// Tests the context menus of overflowed extension actions. -IN_PROC_BROWSER_TEST_F(ToolbarActionViewInteractiveUITest, - MAYBE_TestContextMenuOnOverflowedAction) { - views::MenuController::TurnOffMenuSelectionHoldForTest(); - - // Load an extension that has a home page (important for the context menu's - // first item being enabled). - ASSERT_TRUE(LoadExtension( - test_data_dir_.AppendASCII("ui").AppendASCII("browser_action_popup"))); - base::RunLoop().RunUntilIdle(); // Ensure the extension is fully loaded. - - // Aaaannnnd... Load a bunch of other extensions so that the overflow menu - // is spread across multiple rows. - for (int i = 0; i < 15; ++i) { - scoped_refptr<const extensions::Extension> extension = - extensions::extension_action_test_util::CreateActionExtension( - base::IntToString(i), - extensions::extension_action_test_util::BROWSER_ACTION); - extension_service()->AddExtension(extension.get()); - } - - ASSERT_EQ(16u, browser() - ->window() - ->GetToolbarActionsBar() - ->toolbar_actions_unordered() - .size()); - - // Reduce visible count to 0 so that all actions are overflowed. - ToolbarActionsModel::Get(profile())->SetVisibleIconCount(0); - - // Set a callback for the context menu showing. - bool did_test_while_menu_open = false; - base::Callback<void(ToolbarActionView*)> context_menu_callback( - base::Bind(&OnContextMenuWillShow, &did_test_while_menu_open, browser())); - ToolbarActionView::set_context_menu_callback_for_testing( - &context_menu_callback); - - WrenchToolbarButton* app_menu_button = GetWrenchButtonFromBrowser(browser()); - // Click on the app button, and then right-click on the first toolbar action. - gfx::Point app_button_loc = - test::GetCenterInScreenCoordinates(app_menu_button); - base::RunLoop loop; - ui_controls::SendMouseMove(app_button_loc.x(), app_button_loc.y()); - ui_controls::SendMouseEventsNotifyWhenDone( - ui_controls::LEFT, ui_controls::DOWN | ui_controls::UP, - base::Bind(&TestOverflowedToolbarAction, browser(), ui_controls::RIGHT, - loop.QuitClosure())); - loop.Run(); - - // Test is continued first in TestOverflowedToolbarAction() to right click on - // the action, followed by OnContextMenuWillShow() and - // TestWhileContextMenuOpen(). - - // Make sure we did all the expected tests. - EXPECT_TRUE(did_test_while_menu_open); - - // We should have navigated to the extension's home page, which is google.com. - EXPECT_EQ( - GURL("https://www.google.com/"), - browser()->tab_strip_model()->GetActiveWebContents()->GetVisibleURL()); -} - // Tests that clicking on the toolbar action a second time when the action is // already open results in closing the popup, and doesn't re-open it. IN_PROC_BROWSER_TEST_F(ToolbarActionViewInteractiveUITest,
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index a2ade15..7740a5db 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi
@@ -1924,8 +1924,6 @@ 'browser/net/chrome_url_request_context_getter.h', 'browser/net/connect_interceptor.cc', 'browser/net/connect_interceptor.h', - 'browser/net/cookie_store_util.cc', - 'browser/net/cookie_store_util.h', 'browser/net/crl_set_fetcher.cc', 'browser/net/crl_set_fetcher.h', 'browser/net/dns_probe_runner.cc', @@ -2047,12 +2045,6 @@ 'browser/net/nss_context.h', 'browser/net/nss_context_chromeos.cc', 'browser/net/nss_context_linux.cc', - 'third_party/mozilla_security_manager/nsNSSCertHelper.cpp', - 'third_party/mozilla_security_manager/nsNSSCertHelper.h', - 'third_party/mozilla_security_manager/nsNSSCertificate.cpp', - 'third_party/mozilla_security_manager/nsNSSCertificate.h', - 'third_party/mozilla_security_manager/nsUsageArrayHelper.cpp', - 'third_party/mozilla_security_manager/nsUsageArrayHelper.h', ], 'chrome_browser_password_manager_sources': [ 'browser/password_manager/chrome_password_manager_client.cc', @@ -3218,6 +3210,7 @@ '../components/components.gyp:autofill_content_browser', '../components/components.gyp:browsing_data', '../components/components.gyp:certificate_reporting', + '../components/components.gyp:cookie_config', '../components/components.gyp:data_reduction_proxy_content_browser', '../components/components.gyp:data_use_measurement_content', '../components/components.gyp:devtools_discovery',
diff --git a/chrome/chrome_browser_extensions.gypi b/chrome/chrome_browser_extensions.gypi index 098eae3..65fdc7a 100644 --- a/chrome/chrome_browser_extensions.gypi +++ b/chrome/chrome_browser_extensions.gypi
@@ -851,6 +851,8 @@ 'browser/extensions/unpacked_installer.h', 'browser/extensions/updater/chrome_extension_downloader_factory.cc', 'browser/extensions/updater/chrome_extension_downloader_factory.h', + 'browser/extensions/updater/chrome_update_client_config.cc', + 'browser/extensions/updater/chrome_update_client_config.h', 'browser/extensions/updater/extension_updater.cc', 'browser/extensions/updater/extension_updater.h', 'browser/extensions/user_script_listener.cc',
diff --git a/chrome/chrome_common.gypi b/chrome/chrome_common.gypi index de1cde48..15a442a 100644 --- a/chrome/chrome_common.gypi +++ b/chrome/chrome_common.gypi
@@ -595,6 +595,15 @@ ], }], ['use_nss_certs == 1', { + 'sources': [ + # GN version: //chrome/third_party/mozilla_security_manager + 'third_party/mozilla_security_manager/nsNSSCertHelper.cpp', + 'third_party/mozilla_security_manager/nsNSSCertHelper.h', + 'third_party/mozilla_security_manager/nsNSSCertificate.cpp', + 'third_party/mozilla_security_manager/nsNSSCertificate.h', + 'third_party/mozilla_security_manager/nsUsageArrayHelper.cpp', + 'third_party/mozilla_security_manager/nsUsageArrayHelper.h', + ], 'dependencies': [ '../build/linux/system.gyp:ssl', ],
diff --git a/chrome/common/BUILD.gn b/chrome/common/BUILD.gn index 2d819521..e1f8f3a 100644 --- a/chrome/common/BUILD.gn +++ b/chrome/common/BUILD.gn
@@ -47,10 +47,6 @@ ] public_deps = [ - "//chrome/common:constants", - "//chrome/common/safe_browsing:proto", - ] - deps = [ "//base:base", "//base:i18n", "//base:prefs", @@ -58,12 +54,17 @@ "//chrome:resources", "//chrome:strings", "//chrome/app/theme:theme_resources", + "//chrome/common:constants", + "//chrome/common/safe_browsing:proto", "//chrome/common/variations:fieldtrial_testing_config", "//chrome/installer/util", "//components/cloud_devices/common", "//components/component_updater", "//components/content_settings/core/common", "//components/crash/core/common", + "//components/data_reduction_proxy/content/common", + "//components/dom_distiller/core", + "//components/error_page/common", "//components/favicon_base", "//components/gcm_driver/common", "//components/json_schema", @@ -79,10 +80,20 @@ "//content/public/common", "//crypto", "//extensions/common:common_constants", + "//gin", + "//google_apis", + "//gpu/command_buffer/service", + "//gpu/config", "//net", + "//ppapi/shared_impl", "//skia", "//third_party/icu", "//third_party/zlib:zip", + "//ui/accessibility", + "//ui/base", + "//ui/gfx/ipc", + "//ui/gl", + "//ui/message_center", "//ui/resources:resources", "//url", ] @@ -98,8 +109,9 @@ ] } else { # Non-iOS. - deps += [ + public_deps += [ ":mojo_bindings", + "//chrome/common/net", "//components/visitedlink/common", "//components/autofill/content/common", "//components/autofill/core/common", @@ -110,11 +122,8 @@ "//media", "//ipc", "//third_party/re2", - "//third_party/widevine/cdm:version_h", - ] - public_deps += [ - "//chrome/common/net", "//third_party/mojo/src/mojo/public/cpp/bindings", + "//third_party/widevine/cdm:version_h", ] } @@ -122,7 +131,7 @@ sources += rebase_path(gypi_values.chrome_common_extensions_sources, ".", "//chrome") - deps += [ + public_deps += [ "//device/usb", "//chrome/common/extensions/api", "//extensions/common", @@ -130,6 +139,9 @@ "//extensions:extensions_resources", "//extensions/strings", "//media/cast:net", + + # This dependency is for a header used only by extensions code. + "//ui/keyboard:keyboard_with_content", ] if (is_chromeos) { sources += @@ -142,7 +154,7 @@ if (is_win || is_mac) { sources += rebase_path(gypi_values.chrome_common_win_mac_sources, ".", "//chrome") - deps += [ "//breakpad:client" ] + public_deps += [ "//breakpad:client" ] } if (is_win || is_mac || is_chromeos) { sources += rebase_path(gypi_values.chrome_common_networking_private_sources, @@ -150,21 +162,24 @@ "//chrome") # networking_private_crypto.cc depends on boringssl. - deps += [ "//third_party/boringssl" ] + public_deps += [ "//third_party/boringssl" ] } if (is_mac) { sources += rebase_path(gypi_values.chrome_common_mac_sources, ".", "//chrome") - deps += [ ":app_mode_app_support" ] + public_deps += [ ":app_mode_app_support" ] + } + if (is_chromeos) { + public_deps += [ "//chromeos" ] } if (enable_nacl) { - deps += [ "//components/nacl:nacl_common" ] + public_deps += [ "//components/nacl:nacl_common" ] } # Printing. if (enable_basic_printing || enable_print_preview) { - deps += [ + public_deps += [ "//components/printing/common", "//printing", ] @@ -207,7 +222,7 @@ } if (is_win) { - deps += [ + public_deps += [ "//components/dom_distiller/core", # Needed by chrome_content_client.cc. "//third_party/wtl", ] @@ -219,7 +234,7 @@ if (is_mac) { sources -= [ "channel_info_posix.cc" ] - deps += [ + public_deps += [ "//third_party/mach_override", "//third_party/google_toolbox_for_mac", ] @@ -232,7 +247,7 @@ "ppapi_utils.cc", "ppapi_utils.h", ] - deps += [ "//third_party/adobe/flash:flapper_version_h" ] + public_deps += [ "//third_party/adobe/flash:flapper_version_h" ] } if (enable_plugins && enable_extensions) { sources += [ @@ -244,7 +259,7 @@ sources -= [ "media/webrtc_logging_messages.h" ] } if (enable_configuration_policy) { - deps += [ "//components/policy" ] + public_deps += [ "//components/policy" ] } if (safe_browsing_mode == 1) {
diff --git a/chrome/common/chrome_content_client.cc b/chrome/common/chrome_content_client.cc index c0d6265..4c24a3a1 100644 --- a/chrome/common/chrome_content_client.cc +++ b/chrome/common/chrome_content_client.cc
@@ -68,7 +68,7 @@ #if defined(ENABLE_PLUGINS) #include "content/public/common/pepper_plugin_info.h" -#include "flapper_version.h" // In SHARED_INTERMEDIATE_DIR. +#include "flapper_version.h" // nogncheck In SHARED_INTERMEDIATE_DIR. #include "ppapi/shared_impl/ppapi_permissions.h" #endif
diff --git a/chrome/common/chrome_paths_android.cc b/chrome/common/chrome_paths_android.cc index a78b48d..9184418 100644 --- a/chrome/common/chrome_paths_android.cc +++ b/chrome/common/chrome_paths_android.cc
@@ -7,7 +7,6 @@ #include "base/files/file_path.h" #include "base/logging.h" #include "base/path_service.h" -#include "content/public/common/content_switches.h" namespace chrome {
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index 5e53039..a0f360d 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h
@@ -13,10 +13,6 @@ // Don't add more switch files here. This is linked into some places like the // installer where dependencies should be limited. Instead, have files // directly include your switch file. -// -// TODO(brettw) delete content_switches.h include and make callers include that -// file manually if they need a content switch. -#include "content/public/common/content_switches.h" namespace switches {
diff --git a/chrome/common/crash_keys.cc b/chrome/common/crash_keys.cc index 3cd3cd4..8b2aabf 100644 --- a/chrome/common/crash_keys.cc +++ b/chrome/common/crash_keys.cc
@@ -16,10 +16,12 @@ #include "content/public/common/content_switches.h" #include "ipc/ipc_switches.h" +// Breakpad dependencies exist only on Windows and Mac desktop. Exclude them +// from "gn check" to avoid failures on Linux (it doesn't understand ifdefs). #if defined(OS_MACOSX) -#include "breakpad/src/common/simple_string_dictionary.h" +#include "breakpad/src/common/simple_string_dictionary.h" // nogncheck #elif defined(OS_WIN) -#include "breakpad/src/client/windows/common/ipc_protocol.h" +#include "breakpad/src/client/windows/common/ipc_protocol.h" // nogncheck #elif defined(OS_CHROMEOS) #include "chrome/common/chrome_switches.h" #include "gpu/command_buffer/service/gpu_switches.h"
diff --git a/chrome/common/extensions/extension_process_policy.h b/chrome/common/extensions/extension_process_policy.h index 7231c0f8..2323483 100644 --- a/chrome/common/extensions/extension_process_policy.h +++ b/chrome/common/extensions/extension_process_policy.h
@@ -5,12 +5,12 @@ #ifndef CHROME_COMMON_EXTENSIONS_EXTENSION_PROCESS_POLICY_H_ #define CHROME_COMMON_EXTENSIONS_EXTENSION_PROCESS_POLICY_H_ -class ExtensionSet; class GURL; namespace extensions { class Extension; +class ExtensionSet; // Returns the extension for the given URL. Excludes extension objects for // bookmark apps, which do not use the app process model.
diff --git a/chrome/common/net/BUILD.gn b/chrome/common/net/BUILD.gn index 70e6b72..a6d51519 100644 --- a/chrome/common/net/BUILD.gn +++ b/chrome/common/net/BUILD.gn
@@ -19,6 +19,7 @@ deps = [ "//base", + "//base:i18n", "//chrome:resources", "//chrome:strings", "//components/url_formatter", @@ -44,7 +45,12 @@ } if (use_nss_certs) { - deps += [ "//crypto:platform" ] + deps += [ + "//chrome/third_party/mozilla_security_manager", + "//crypto:platform", + ] + allow_circular_includes_from = + [ "//chrome/third_party/mozilla_security_manager" ] } else { sources -= [ "x509_certificate_model_nss.cc" ] }
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index 46a7f9e9..d454384f 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc
@@ -1306,14 +1306,6 @@ const char kStabilityPluginCrashes[] = "crashes"; const char kStabilityPluginLoadingErrors[] = "loading_errors"; -// The keys below are strictly increasing counters over the lifetime of -// a chrome installation. They are (optionally) sent up to the uninstall -// survey in the event of uninstallation. -const char kUninstallLastLaunchTimeSec[] = - "uninstall_metrics.last_launch_time_sec"; -const char kUninstallLastObservedRunTimeSec[] = - "uninstall_metrics.last_observed_running_time_sec"; - // String containing the version of Chrome for which Chrome will not prompt the // user about setting Chrome as the default browser. const char kBrowserSuppressDefaultBrowserPrompt[] =
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index b9bc4e88..400ac45f 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h
@@ -454,9 +454,6 @@ extern const char kStabilityPluginCrashes[]; extern const char kStabilityPluginLoadingErrors[]; -extern const char kUninstallLastLaunchTimeSec[]; -extern const char kUninstallLastObservedRunTimeSec[]; - extern const char kBrowserSuppressDefaultBrowserPrompt[]; extern const char kBrowserWindowPlacement[];
diff --git a/chrome/installer/util/delete_after_reboot_helper.cc b/chrome/installer/util/delete_after_reboot_helper.cc index bc7cd2b..c9cf0fe7 100644 --- a/chrome/installer/util/delete_after_reboot_helper.cc +++ b/chrome/installer/util/delete_after_reboot_helper.cc
@@ -253,10 +253,10 @@ DWORD last_error = ::GetLastError(); DLOG_IF(WARNING, length == 0 && last_error != ERROR_PATH_NOT_FOUND) << __FUNCTION__ << " gle=" << last_error; - if (length == 0) { - // GetShortPathName fails if the path is no longer present. Instead of - // returning an empty string, just return the original string. This will - // serve our purposes. + if ((length == 0) || (length > MAX_PATH)) { + // GetShortPathName fails if the path is no longer present or cannot be + // put in the size buffer provided. Instead of returning an empty string, + // just return the original string. This will serve our purposes. return path; }
diff --git a/chrome/installer/util/shell_util.cc b/chrome/installer/util/shell_util.cc index a753f80..37ecbcfc 100644 --- a/chrome/installer/util/shell_util.cc +++ b/chrome/installer/util/shell_util.cc
@@ -1307,10 +1307,10 @@ const base::FilePath& chrome_exe, const wchar_t* const* protocols, size_t num_protocols) { - // Get its short (8.3) form. - base::string16 short_app_path; - if (!ShortNameFromPath(chrome_exe, &short_app_path)) - return ShellUtil::UNKNOWN_DEFAULT; + // Get its short (8.3) form if possible. + base::string16 app_path; + if (!ShortNameFromPath(chrome_exe, &app_path)) + app_path = chrome_exe.value(); const HKEY root_key = HKEY_CLASSES_ROOT; base::string16 key_path; @@ -1330,11 +1330,14 @@ // Need to normalize path in case it's been munged. command_line = base::CommandLine::FromString(value); - if (!ShortNameFromPath(command_line.GetProgram(), &short_path)) - return ShellUtil::UNKNOWN_DEFAULT; - - if (!base::FilePath::CompareEqualIgnoreCase(short_path, short_app_path)) - return ShellUtil::NOT_DEFAULT; + if (ShortNameFromPath(command_line.GetProgram(), &short_path)) { + if (!base::FilePath::CompareEqualIgnoreCase(short_path, app_path)) + return ShellUtil::NOT_DEFAULT; + } else { + if (!base::FilePath::CompareEqualIgnoreCase( + command_line.GetProgram().value(), app_path)) + return ShellUtil::NOT_DEFAULT; + } } return ShellUtil::IS_DEFAULT;
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 218f1d4..18fe2c9 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -780,9 +780,7 @@ # The _run targets exist only for compatibility w/ GYP. group("browser_tests_run") { testonly = true - data_deps = [ - ":browser_tests", - ] + data_deps = [ ":browser_tests" ] } test("browser_tests") { @@ -1333,9 +1331,7 @@ "//third_party/WebKit/public:blink", ] - data_deps = [ - "//third_party/mesa:osmesa", - ] + data_deps = [ "//third_party/mesa:osmesa" ] if (cld_version == 2) { # Language detection is irrelevant to sync, so it can depend on any
diff --git a/chrome/test/data/extensions/ui/browser_action_popup/manifest.json b/chrome/test/data/extensions/ui/browser_action_popup/manifest.json index 3371986..9669f940 100644 --- a/chrome/test/data/extensions/ui/browser_action_popup/manifest.json +++ b/chrome/test/data/extensions/ui/browser_action_popup/manifest.json
@@ -5,6 +5,5 @@ "version": "0.1", "browser_action": { "default_popup": "popup.html" - }, - "homepage_url": "https://www.google.com/" + } }
diff --git a/chrome/third_party/mozilla_security_manager/BUILD.gn b/chrome/third_party/mozilla_security_manager/BUILD.gn new file mode 100644 index 0000000..5aa58cf --- /dev/null +++ b/chrome/third_party/mozilla_security_manager/BUILD.gn
@@ -0,0 +1,24 @@ +# 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. + +source_set("mozilla_security_manager") { + sources = [ + "nsNSSCertHelper.cpp", + "nsNSSCertHelper.h", + "nsNSSCertificate.cpp", + "nsNSSCertificate.h", + "nsUsageArrayHelper.cpp", + "nsUsageArrayHelper.h", + ] + + deps = [ + "//base", + "//base:i18n", + "//chrome/app:generated_resources", + "//crypto:platform", + "//net", + "//third_party/icu", + "//ui/base", + ] +}
diff --git a/chrome/utility/chrome_content_utility_client.cc b/chrome/utility/chrome_content_utility_client.cc index 3d09c61..ee6c0366 100644 --- a/chrome/utility/chrome_content_utility_client.cc +++ b/chrome/utility/chrome_content_utility_client.cc
@@ -44,11 +44,8 @@ #endif #if defined(ENABLE_EXTENSIONS) -#include "chrome/common/extensions/chrome_utility_extensions_messages.h" #include "chrome/utility/extensions/extensions_handler.h" #include "chrome/utility/image_writer/image_writer_handler.h" -#include "chrome/utility/media_galleries/ipc_data_source.h" -#include "chrome/utility/media_galleries/media_metadata_parser.h" #endif #if defined(ENABLE_PRINT_PREVIEW) || defined(OS_WIN) @@ -73,17 +70,6 @@ content::UtilityThread::Get()->ReleaseProcessIfNeeded(); } -#if defined(ENABLE_EXTENSIONS) -void FinishParseMediaMetadata( - metadata::MediaMetadataParser* /* parser */, - const extensions::api::media_galleries::MediaMetadata& metadata, - const std::vector<metadata::AttachedImage>& attached_images) { - Send(new ChromeUtilityHostMsg_ParseMediaMetadata_Finished( - true, *metadata.ToValue(), attached_images)); - ReleaseProcessIfNeeded(); -} -#endif - #if !defined(OS_ANDROID) void CreateProxyResolverFactory( mojo::InterfaceRequest<net::interfaces::ProxyResolverFactory> request) { @@ -135,7 +121,7 @@ #endif #if defined(ENABLE_EXTENSIONS) - handlers_.push_back(new extensions::ExtensionsHandler()); + handlers_.push_back(new extensions::ExtensionsHandler(this)); handlers_.push_back(new image_writer::ImageWriterHandler()); #endif @@ -199,12 +185,8 @@ #if defined(OS_MACOSX) IPC_MESSAGE_HANDLER(ChromeUtilityMsg_AnalyzeDmgFileForDownloadProtection, OnAnalyzeDmgFileForDownloadProtection) -#endif -#endif -#if defined(ENABLE_EXTENSIONS) - IPC_MESSAGE_HANDLER(ChromeUtilityMsg_ParseMediaMetadata, - OnParseMediaMetadata) -#endif +#endif // defined(OS_MACOSX) +#endif // defined(FULL_SAFE_BROWSING) #if defined(OS_CHROMEOS) IPC_MESSAGE_HANDLER(ChromeUtilityMsg_CreateZipFile, OnCreateZipFile) #endif @@ -229,6 +211,11 @@ #endif } +void ChromeContentUtilityClient::AddHandler( + scoped_ptr<UtilityMessageHandler> handler) { + handlers_.push_back(handler.Pass()); +} + // static void ChromeContentUtilityClient::PreSandboxStartup() { #if defined(ENABLE_EXTENSIONS) @@ -415,21 +402,6 @@ results)); ReleaseProcessIfNeeded(); } -#endif +#endif // defined(OS_MACOSX) -#endif - -#if defined(ENABLE_EXTENSIONS) -// TODO(thestig): Try to move this to -// chrome/utility/extensions/extensions_handler.cc. -void ChromeContentUtilityClient::OnParseMediaMetadata( - const std::string& mime_type, int64 total_size, bool get_attached_images) { - // Only one IPCDataSource may be created and added to the list of handlers. - metadata::IPCDataSource* source = new metadata::IPCDataSource(total_size); - handlers_.push_back(source); - - metadata::MediaMetadataParser* parser = new metadata::MediaMetadataParser( - source, mime_type, get_attached_images); - parser->Start(base::Bind(&FinishParseMediaMetadata, base::Owned(parser))); -} -#endif +#endif // defined(FULL_SAFE_BROWSING)
diff --git a/chrome/utility/chrome_content_utility_client.h b/chrome/utility/chrome_content_utility_client.h index 039791b..1302cd12 100644 --- a/chrome/utility/chrome_content_utility_client.h +++ b/chrome/utility/chrome_content_utility_client.h
@@ -30,6 +30,8 @@ bool OnMessageReceived(const IPC::Message& message) override; void RegisterMojoServices(content::ServiceRegistry* registry) override; + void AddHandler(scoped_ptr<UtilityMessageHandler> handler); + static void PreSandboxStartup(); // Shared with extensions::ExtensionsHandler. @@ -72,13 +74,8 @@ #if defined(OS_MACOSX) void OnAnalyzeDmgFileForDownloadProtection( const IPC::PlatformFileForTransit& dmg_file); -#endif -#endif -#if defined(ENABLE_EXTENSIONS) - void OnParseMediaMetadata(const std::string& mime_type, - int64 total_size, - bool get_attached_images); -#endif +#endif // defined(OS_MACOSX) +#endif // defined(FULL_SAFE_BROWSING) typedef ScopedVector<UtilityMessageHandler> Handlers; Handlers handlers_;
diff --git a/chrome/utility/extensions/extensions_handler.cc b/chrome/utility/extensions/extensions_handler.cc index 942545e..25586e9b 100644 --- a/chrome/utility/extensions/extensions_handler.cc +++ b/chrome/utility/extensions/extensions_handler.cc
@@ -12,6 +12,8 @@ #include "chrome/common/media_galleries/metadata_types.h" #include "chrome/utility/chrome_content_utility_client.h" #include "chrome/utility/media_galleries/image_metadata_extractor.h" +#include "chrome/utility/media_galleries/ipc_data_source.h" +#include "chrome/utility/media_galleries/media_metadata_parser.h" #include "content/public/common/content_paths.h" #include "content/public/utility/utility_thread.h" #include "extensions/common/extension.h" @@ -51,9 +53,19 @@ content::UtilityThread::Get()->ReleaseProcessIfNeeded(); } +void FinishParseMediaMetadata( + metadata::MediaMetadataParser* /* parser */, + const extensions::api::media_galleries::MediaMetadata& metadata, + const std::vector<metadata::AttachedImage>& attached_images) { + Send(new ChromeUtilityHostMsg_ParseMediaMetadata_Finished( + true, *metadata.ToValue(), attached_images)); + ReleaseProcessIfNeeded(); +} + } // namespace -ExtensionsHandler::ExtensionsHandler() { +ExtensionsHandler::ExtensionsHandler(ChromeContentUtilityClient* utility_client) + : utility_client_(utility_client) { ExtensionsClient::Set(ChromeExtensionsClient::GetInstance()); } @@ -73,6 +85,9 @@ bool handled = true; IPC_BEGIN_MESSAGE_MAP(ExtensionsHandler, message) IPC_MESSAGE_HANDLER(ChromeUtilityMsg_CheckMediaFile, OnCheckMediaFile) + IPC_MESSAGE_HANDLER(ChromeUtilityMsg_ParseMediaMetadata, + OnParseMediaMetadata) + #if defined(OS_WIN) IPC_MESSAGE_HANDLER(ChromeUtilityMsg_ParseITunesPrefXml, OnParseITunesPrefXml) @@ -113,6 +128,17 @@ ReleaseProcessIfNeeded(); } +void ExtensionsHandler::OnParseMediaMetadata( + const std::string& mime_type, int64 total_size, bool get_attached_images) { + // Only one IPCDataSource may be created and added to the list of handlers. + scoped_ptr<metadata::IPCDataSource> source( + new metadata::IPCDataSource(total_size)); + metadata::MediaMetadataParser* parser = new metadata::MediaMetadataParser( + source.get(), mime_type, get_attached_images); + utility_client_->AddHandler(source.Pass()); + parser->Start(base::Bind(&FinishParseMediaMetadata, base::Owned(parser))); +} + #if defined(OS_WIN) void ExtensionsHandler::OnParseITunesPrefXml( const std::string& itunes_xml_data) {
diff --git a/chrome/utility/extensions/extensions_handler.h b/chrome/utility/extensions/extensions_handler.h index 06f3601..fadf3e81 100644 --- a/chrome/utility/extensions/extensions_handler.h +++ b/chrome/utility/extensions/extensions_handler.h
@@ -16,6 +16,8 @@ #error "Extensions must be enabled" #endif +class ChromeContentUtilityClient; + namespace metadata { class MediaMetadataParser; } @@ -25,7 +27,7 @@ // Dispatches IPCs for Chrome extensions utility messages. class ExtensionsHandler : public UtilityMessageHandler { public: - ExtensionsHandler(); + explicit ExtensionsHandler(ChromeContentUtilityClient* utility_client); ~ExtensionsHandler() override; static void PreSandboxStartup(); @@ -38,6 +40,10 @@ void OnCheckMediaFile(int64 milliseconds_of_decoding, const IPC::PlatformFileForTransit& media_file); + void OnParseMediaMetadata(const std::string& mime_type, + int64 total_size, + bool get_attached_images); + #if defined(OS_WIN) void OnParseITunesPrefXml(const std::string& itunes_xml_data); #endif // defined(OS_WIN) @@ -65,6 +71,9 @@ UtilityHandler utility_handler_; + // The client that owns this. + ChromeContentUtilityClient* const utility_client_; + DISALLOW_COPY_AND_ASSIGN(ExtensionsHandler); };
diff --git a/chromecast/media/audio/cast_audio_output_stream.cc b/chromecast/media/audio/cast_audio_output_stream.cc index 73c935b3..e55f127 100644 --- a/chromecast/media/audio/cast_audio_output_stream.cc +++ b/chromecast/media/audio/cast_audio_output_stream.cc
@@ -86,7 +86,9 @@ backend_task_runner_.reset(new TaskRunnerImpl()); MediaPipelineDeviceParams device_params( - MediaPipelineDeviceParams::kModeIgnorePts, backend_task_runner_.get()); + MediaPipelineDeviceParams::kModeIgnorePts, + MediaPipelineDeviceParams::kAudioStreamSoundEffects, + backend_task_runner_.get()); backend_ = audio_manager->CreateMediaPipelineBackend(device_params); if (backend_) decoder_ = InitializeBackend(audio_params_, backend_.get(), this);
diff --git a/chromecast/public/media/media_pipeline_device_params.h b/chromecast/public/media/media_pipeline_device_params.h index b307dc4..680da27 100644 --- a/chromecast/public/media/media_pipeline_device_params.h +++ b/chromecast/public/media/media_pipeline_device_params.h
@@ -27,14 +27,36 @@ kModeIgnorePtsAndVSync = 2, }; + enum AudioStreamType { + // "Real" audio stream. If this stream underruns, all audio output may pause + // until more real stream data is available. + kAudioStreamNormal = 0, + // Sound-effects audio stream. May be interrupted if a real audio stream + // is created with a different sample rate. Underruns on an effects stream + // do not affect output of real audio streams. + kAudioStreamSoundEffects = 1, + }; + MediaPipelineDeviceParams(TaskRunner* task_runner_in) - : sync_type(kModeSyncPts), task_runner(task_runner_in) {} + : sync_type(kModeSyncPts), + audio_type(kAudioStreamNormal), + task_runner(task_runner_in) {} MediaPipelineDeviceParams(MediaSyncType sync_type_in, TaskRunner* task_runner_in) - : sync_type(sync_type_in), task_runner(task_runner_in) {} + : sync_type(sync_type_in), + audio_type(kAudioStreamNormal), + task_runner(task_runner_in) {} + + MediaPipelineDeviceParams(MediaSyncType sync_type_in, + AudioStreamType audio_type_in, + TaskRunner* task_runner_in) + : sync_type(sync_type_in), + audio_type(audio_type_in), + task_runner(task_runner_in) {} const MediaSyncType sync_type; + const AudioStreamType audio_type; // task_runner allows backend implementations to post tasks to the media // thread. Since all calls from cast_shell into the backend are made on
diff --git a/cloud_print/service/win/BUILD.gn b/cloud_print/service/win/BUILD.gn index 211ccc33..2c050b0b 100644 --- a/cloud_print/service/win/BUILD.gn +++ b/cloud_print/service/win/BUILD.gn
@@ -44,24 +44,7 @@ output = "$target_gen_dir/cloud_print_service_exe_version.rc" } -executable("cloud_print_service_config") { - sources = [ - "cloud_print_service_config.cc", - ] - - configs -= [ "//build/config/win:console" ] - configs += [ "//build/config/win:windowed" ] - - deps = [ - ":config_version", - ":exe_manifest", - "//cloud_print/common:install_utils", - "//cloud_print/service:resources", - "//cloud_print/service:lib", - ] - - libs = [ "secur32.lib" ] - +config("cloud_print_service_config_warnings") { # TODO: Remove once cloud_print_service_config.cc no longer depends on # atlapp.h, http://crbug.com/5027 if (is_clang) { @@ -81,6 +64,28 @@ } } +executable("cloud_print_service_config") { + sources = [ + "cloud_print_service_config.cc", + ] + + configs -= [ "//build/config/win:console" ] + configs += [ + "//build/config/win:windowed", + ":cloud_print_service_config_warnings", + ] + + deps = [ + ":config_version", + ":exe_manifest", + "//cloud_print/common:install_utils", + "//cloud_print/service:resources", + "//cloud_print/service:lib", + ] + + libs = [ "secur32.lib" ] +} + process_version("config_version") { template_file = chrome_version_rc_template sources = [
diff --git a/cloud_print/virtual_driver/win/port_monitor/BUILD.gn b/cloud_print/virtual_driver/win/port_monitor/BUILD.gn index a9e5b359..f6e727f 100644 --- a/cloud_print/virtual_driver/win/port_monitor/BUILD.gn +++ b/cloud_print/virtual_driver/win/port_monitor/BUILD.gn
@@ -14,8 +14,6 @@ arch_suffix = "" } -print("port_monitor $current_toolchain") - shared_library("port_monitor") { output_name = "gcp_portmon$arch_suffix"
diff --git a/components/BUILD.gn b/components/BUILD.gn index f1e32cd..03c729c 100644 --- a/components/BUILD.gn +++ b/components/BUILD.gn
@@ -60,6 +60,7 @@ "//components/compression", "//components/content_settings/core/browser", "//components/content_settings/core/common", + "//components/cookie_config", "//components/crash/content/app", "//components/crash/content/browser", "//components/crx_file",
diff --git a/components/autofill/core/browser/suggestion.cc b/components/autofill/core/browser/suggestion.cc index c5b150e..22d4ac7 100644 --- a/components/autofill/core/browser/suggestion.cc +++ b/components/autofill/core/browser/suggestion.cc
@@ -5,8 +5,6 @@ #include "components/autofill/core/browser/suggestion.h" #include "base/strings/utf_string_conversions.h" -#include "components/autofill/core/browser/autofill_profile.h" -#include "components/autofill/core/browser/credit_card.h" namespace autofill {
diff --git a/components/autofill/core/browser/suggestion.h b/components/autofill/core/browser/suggestion.h index ebf16073..930ab23 100644 --- a/components/autofill/core/browser/suggestion.h +++ b/components/autofill/core/browser/suggestion.h
@@ -7,16 +7,11 @@ #include <string> -#include "base/memory/scoped_ptr.h" #include "base/strings/string16.h" namespace autofill { -class AutofillProfile; -class CreditCard; - struct Suggestion { - public: enum MatchMode { PREFIX_MATCH, // for prefix matched suggestions; SUBSTRING_MATCH // for substring matched suggestions;
diff --git a/components/component_updater/configurator_impl.cc b/components/component_updater/configurator_impl.cc index cc6d7f0..fb8f1db 100644 --- a/components/component_updater/configurator_impl.cc +++ b/components/component_updater/configurator_impl.cc
@@ -192,4 +192,8 @@ return background_downloads_enabled_; } +void ConfiguratorImpl::set_enable_alt_source_url(bool enable_alt_source_url) { + fallback_to_alt_source_url_enabled_ = enable_alt_source_url; +} + } // namespace component_updater
diff --git a/components/component_updater/configurator_impl.h b/components/component_updater/configurator_impl.h index df58473..b2e75a9 100644 --- a/components/component_updater/configurator_impl.h +++ b/components/component_updater/configurator_impl.h
@@ -77,6 +77,11 @@ // non on-demand components. bool UseBackgroundDownloader() const; + // Setting this to false means that we'll only use secure transport (eg https) + // for update/ping urls. This is already false by default everywhere but older + // versions of Windows XP. + void set_enable_alt_source_url(bool enable_alt_source_url); + private: net::URLRequestContextGetter* url_request_getter_; std::string extra_info_;
diff --git a/components/components.gyp b/components/components.gyp index 85ac077..39e829f7 100644 --- a/components/components.gyp +++ b/components/components.gyp
@@ -21,6 +21,7 @@ 'component_updater.gypi', 'compression.gypi', 'content_settings.gypi', + 'cookie_config.gypi', 'crash.gypi', 'cronet.gypi', 'crx_file.gypi',
diff --git a/components/cookie_config.gypi b/components/cookie_config.gypi new file mode 100644 index 0000000..4c3e8f7 --- /dev/null +++ b/components/cookie_config.gypi
@@ -0,0 +1,26 @@ +# 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. + +{ + 'targets': [ + { + # GN version: //components/cookie_config + 'target_name': 'cookie_config', + 'type': 'static_library', + 'dependencies': [ + '../base/base.gyp:base', + '../net/net.gyp:net', + 'os_crypt', + ], + 'include_dirs': [ + '..', + ], + 'sources': [ + 'cookie_config/cookie_store_util.cc', + 'cookie_config/cookie_store_util.h', + ], + }, + ], +} +
diff --git a/components/cookie_config/BUILD.gn b/components/cookie_config/BUILD.gn new file mode 100644 index 0000000..fc3b632 --- /dev/null +++ b/components/cookie_config/BUILD.gn
@@ -0,0 +1,17 @@ +# 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. + +# GYP version: components/cookie_config.gypi:cookie_config +source_set("cookie_config") { + sources = [ + "cookie_store_util.cc", + "cookie_store_util.h", + ] + + deps = [ + "//base", + "//components/os_crypt", + "//net", + ] +}
diff --git a/components/cookie_config/DEPS b/components/cookie_config/DEPS new file mode 100644 index 0000000..091c0c8 --- /dev/null +++ b/components/cookie_config/DEPS
@@ -0,0 +1,4 @@ +include_rules = [ + "+components/os_crypt", + "+net/extras/sqlite", +]
diff --git a/components/cookie_config/OWNERS b/components/cookie_config/OWNERS new file mode 100644 index 0000000..6fe35f0 --- /dev/null +++ b/components/cookie_config/OWNERS
@@ -0,0 +1,2 @@ +blundell@chromium.org +rdsmith@chromium.org
diff --git a/chrome/browser/net/cookie_store_util.cc b/components/cookie_config/cookie_store_util.cc similarity index 85% rename from chrome/browser/net/cookie_store_util.cc rename to components/cookie_config/cookie_store_util.cc index d3882ef..b900ac6 100644 --- a/chrome/browser/net/cookie_store_util.cc +++ b/components/cookie_config/cookie_store_util.cc
@@ -2,18 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/net/cookie_store_util.h" +#include "components/cookie_config/cookie_store_util.h" #include "base/lazy_instance.h" -#include "chrome/browser/browser_process.h" -#include "chrome/common/chrome_constants.h" -#include "chrome/common/chrome_switches.h" #include "components/os_crypt/os_crypt.h" -#include "content/public/common/content_constants.h" -#include "extensions/common/constants.h" #include "net/extras/sqlite/cookie_crypto_delegate.h" -namespace chrome_browser_net { +namespace cookie_config { #if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX) namespace { @@ -67,10 +62,10 @@ net::CookieCryptoDelegate* GetCookieCryptoDelegate() { return g_cookie_crypto_delegate.Pointer(); } -#else // defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX) +#else // defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX) net::CookieCryptoDelegate* GetCookieCryptoDelegate() { return NULL; } #endif // defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX) -} // namespace chrome_browser_net +} // namespace cookie_config
diff --git a/components/cookie_config/cookie_store_util.h b/components/cookie_config/cookie_store_util.h new file mode 100644 index 0000000..893e6a0 --- /dev/null +++ b/components/cookie_config/cookie_store_util.h
@@ -0,0 +1,21 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_COOKIE_CONFIG_COOKIE_STORE_UTIL_H_ +#define COMPONENTS_COOKIE_CONFIG_COOKIE_STORE_UTIL_H_ + +namespace net { +class CookieCryptoDelegate; +} // namespace net + +namespace cookie_config { + +// Factory method for returning a CookieCryptoDelegate if one is appropriate for +// this platform. The object returned is a LazyInstance. Ownership is not +// transferred. +net::CookieCryptoDelegate* GetCookieCryptoDelegate(); + +} // namespace cookie_config + +#endif // COMPONENTS_COOKIE_CONFIG_COOKIE_STORE_UTIL_H_
diff --git a/components/html_viewer/ax_provider_apptest.cc b/components/html_viewer/ax_provider_apptest.cc index cda4538b..ac703bc 100644 --- a/components/html_viewer/ax_provider_apptest.cc +++ b/components/html_viewer/ax_provider_apptest.cc
@@ -7,9 +7,10 @@ #include "base/run_loop.h" #include "base/strings/stringprintf.h" #include "base/test/test_timeouts.h" -#include "components/mus/public/cpp/tests/view_manager_test_base.h" -#include "components/mus/public/cpp/view.h" -#include "components/mus/public/cpp/view_tree_connection.h" +#include "base/time/time.h" +#include "components/mus/public/cpp/tests/window_server_test_base.h" +#include "components/mus/public/cpp/window.h" +#include "components/mus/public/cpp/window_tree_connection.h" #include "components/web_view/public/interfaces/frame.mojom.h" #include "mojo/application/public/cpp/application_impl.h" #include "mojo/application/public/cpp/application_test_base.h" @@ -67,7 +68,7 @@ } // namespace -using AXProviderTest = mus::ViewManagerTestBase; +using AXProviderTest = mus::WindowServerTestBase; TEST_F(AXProviderTest, HelloWorld) { // Start a test server for net/data/test.html access. @@ -84,11 +85,11 @@ scoped_ptr<ApplicationConnection> connection = application_impl()->ConnectToApplication(request.Pass()); - // Embed the html_viewer in a View. + // Embed the html_viewer in a Window. ViewTreeClientPtr tree_client; connection->ConnectToService(&tree_client); - mus::View* embed_view = window_manager()->CreateView(); - embed_view->Embed(tree_client.Pass()); + mus::Window* embed_window = window_manager()->CreateWindow(); + embed_window->Embed(tree_client.Pass()); TestFrame frame; web_view::mojom::FramePtr frame_ptr; @@ -97,14 +98,15 @@ mojo::Array<web_view::mojom::FrameDataPtr> array(1u); array[0] = web_view::mojom::FrameData::New().Pass(); - array[0]->frame_id = embed_view->id(); + array[0]->frame_id = embed_window->id(); array[0]->parent_id = 0u; web_view::mojom::FrameClientPtr frame_client; connection->ConnectToService(&frame_client); - frame_client->OnConnect(frame_ptr.Pass(), 1u, embed_view->id(), - web_view::mojom::VIEW_CONNECT_TYPE_USE_NEW, - array.Pass(), base::Closure()); + frame_client->OnConnect( + frame_ptr.Pass(), 1u, embed_window->id(), + web_view::mojom::VIEW_CONNECT_TYPE_USE_NEW, array.Pass(), + base::TimeTicks::Now().ToInternalValue(), base::Closure()); // Connect to the AxProvider of the HTML document and get the AxTree. AxProviderPtr ax_provider;
diff --git a/components/html_viewer/document_resource_waiter.cc b/components/html_viewer/document_resource_waiter.cc index fdc96ac..bc6731d73 100644 --- a/components/html_viewer/document_resource_waiter.cc +++ b/components/html_viewer/document_resource_waiter.cc
@@ -7,7 +7,7 @@ #include "components/html_viewer/global_state.h" #include "components/html_viewer/html_document.h" #include "components/html_viewer/html_frame_tree_manager.h" -#include "components/mus/public/cpp/view.h" +#include "components/mus/public/cpp/window.h" using web_view::mojom::ViewConnectType; @@ -21,7 +21,7 @@ response_(response.Pass()), root_(nullptr), change_id_(0u), - view_id_(0u), + window_id_(0u), view_connect_type_(web_view::mojom::VIEW_CONNECT_TYPE_USE_NEW), frame_client_binding_(this), is_ready_(false), @@ -40,7 +40,7 @@ web_view::mojom::FramePtr* frame, mojo::Array<web_view::mojom::FrameDataPtr>* frame_data, uint32_t* change_id, - uint32_t* view_id, + uint32_t* window_id, ViewConnectType* view_connect_type, OnConnectCallback* on_connect_callback) { DCHECK(is_ready_); @@ -48,7 +48,7 @@ *frame = frame_.Pass(); *frame_data = frame_data_.Pass(); *change_id = change_id_; - *view_id = view_id_; + *window_id = window_id_; *view_connect_type = view_connect_type_; *on_connect_callback = on_connect_callback_; } @@ -57,7 +57,7 @@ return response_.Pass(); } -void DocumentResourceWaiter::SetRoot(mus::View* root) { +void DocumentResourceWaiter::SetRoot(mus::Window* root) { DCHECK(!root_); root_ = root; root_->AddObserver(this); @@ -123,16 +123,19 @@ void DocumentResourceWaiter::OnConnect( web_view::mojom::FramePtr frame, uint32_t change_id, - uint32_t view_id, + uint32_t window_id, ViewConnectType view_connect_type, mojo::Array<web_view::mojom::FrameDataPtr> frame_data, + int64_t navigation_start_time_ticks, const OnConnectCallback& callback) { DCHECK(frame_data_.is_null()); change_id_ = change_id; - view_id_ = view_id; + window_id_ = window_id; view_connect_type_ = view_connect_type; frame_ = frame.Pass(); frame_data_ = frame_data.Pass(); + navigation_start_time_ = + base::TimeTicks::FromInternalValue(navigation_start_time_ticks); on_connect_callback_ = callback; CHECK(frame_data_.size() > 0u); frame_client_request_ = frame_client_binding_.Unbind(); @@ -214,14 +217,14 @@ NOTREACHED(); } -void DocumentResourceWaiter::OnViewViewportMetricsChanged( - mus::View* view, +void DocumentResourceWaiter::OnWindowViewportMetricsChanged( + mus::Window* window, const mojo::ViewportMetrics& old_metrics, const mojo::ViewportMetrics& new_metrics) { UpdateIsReady(); } -void DocumentResourceWaiter::OnViewDestroyed(mus::View* view) { +void DocumentResourceWaiter::OnWindowDestroyed(mus::Window* window) { root_->RemoveObserver(this); root_ = nullptr; }
diff --git a/components/html_viewer/document_resource_waiter.h b/components/html_viewer/document_resource_waiter.h index 7784548..be22006 100644 --- a/components/html_viewer/document_resource_waiter.h +++ b/components/html_viewer/document_resource_waiter.h
@@ -6,16 +6,13 @@ #define COMPONENTS_HTML_VIEWER_DOCUMENT_RESOURCE_WAITER_H_ #include "base/basictypes.h" +#include "base/time/time.h" #include "components/html_viewer/html_frame_tree_manager_observer.h" -#include "components/mus/public/cpp/view_observer.h" +#include "components/mus/public/cpp/window_observer.h" #include "components/web_view/public/interfaces/frame.mojom.h" #include "mojo/services/network/public/interfaces/url_loader.mojom.h" #include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h" -namespace mojo { -class View; -} - namespace html_viewer { class HTMLDocument; @@ -27,7 +24,7 @@ // assumed HTMLDocument will call back for the FrameClient and FrameData. class DocumentResourceWaiter : public web_view::mojom::FrameClient, public HTMLFrameTreeManagerObserver, - public mus::ViewObserver { + public mus::WindowObserver { public: DocumentResourceWaiter(GlobalState* global_state, mojo::URLResponsePtr response, @@ -39,7 +36,7 @@ frame_client_request, web_view::mojom::FramePtr* frame, mojo::Array<web_view::mojom::FrameDataPtr>* frame_data, - uint32_t* view_id, + uint32_t* window_id, uint32_t* change_id, web_view::mojom::ViewConnectType* view_connect_type, OnConnectCallback* on_connect_callback); @@ -51,8 +48,12 @@ // See class description. bool is_ready() const { return is_ready_; } - void SetRoot(mus::View* root); - mus::View* root() { return root_; } + base::TimeTicks navigation_start_time() const { + return navigation_start_time_; + } + + void SetRoot(mus::Window* root); + mus::Window* root() { return root_; } void Bind(mojo::InterfaceRequest<web_view::mojom::FrameClient> request); @@ -63,9 +64,10 @@ // web_view::mojom::FrameClient: void OnConnect(web_view::mojom::FramePtr frame, uint32_t change_id, - uint32_t view_id, + uint32_t window_id, web_view::mojom::ViewConnectType view_connect_type, mojo::Array<web_view::mojom::FrameDataPtr> frame_data, + int64_t navigation_start_time_ticks, const OnConnectCallback& callback) override; void OnFrameAdded(uint32_t change_id, web_view::mojom::FrameDataPtr frame_data) override; @@ -92,12 +94,12 @@ bool reset) override; void StopHighlightingFindResults() override; - // ViewObserver: - void OnViewViewportMetricsChanged( - mus::View* view, + // WindowObserver: + void OnWindowViewportMetricsChanged( + mus::Window* window, const mojo::ViewportMetrics& old_metrics, const mojo::ViewportMetrics& new_metrics) override; - void OnViewDestroyed(mus::View* view) override; + void OnWindowDestroyed(mus::Window* window) override; // HTMLFrameTreeManagerObserver: void OnHTMLFrameTreeManagerChangeIdAdvanced() override; @@ -106,11 +108,12 @@ GlobalState* global_state_; HTMLDocument* document_; mojo::URLResponsePtr response_; - mus::View* root_; + mus::Window* root_; web_view::mojom::FramePtr frame_; mojo::Array<web_view::mojom::FrameDataPtr> frame_data_; uint32_t change_id_; - uint32_t view_id_; + uint32_t window_id_; + base::TimeTicks navigation_start_time_; web_view::mojom::ViewConnectType view_connect_type_; OnConnectCallback on_connect_callback_;
diff --git a/components/html_viewer/global_state.cc b/components/html_viewer/global_state.cc index e9c295f..fa3eb705 100644 --- a/components/html_viewer/global_state.cc +++ b/components/html_viewer/global_state.cc
@@ -20,6 +20,7 @@ #include "third_party/WebKit/public/web/WebRuntimeFeatures.h" #include "ui/base/resource/resource_bundle.h" #include "ui/base/ui_base_paths.h" +#include "ui/gfx/display.h" #include "ui/mojo/init/ui_init.h" #include "v8/include/v8.h" @@ -56,16 +57,26 @@ return paths; } +// TODO(sky): convert to using DisplayService. +std::vector<gfx::Display> DisplaysFromSizeAndScale( + const gfx::Size& screen_size_in_pixels, + float device_pixel_ratio) { + std::vector<gfx::Display> displays(1); + displays[0].set_id(2000); + displays[0].SetScaleAndBounds(device_pixel_ratio, + gfx::Rect(screen_size_in_pixels)); + return displays; +} + } // namespace GlobalState::GlobalState(mojo::ApplicationImpl* app) : app_(app), - resource_loader_(app->shell(), GetResourcePaths()), + resource_loader_(app, GetResourcePaths()), did_init_(false), device_pixel_ratio_(1.f), discardable_memory_allocator_(kDesiredMaxMemory), - compositor_thread_("compositor thread") { -} + compositor_thread_("compositor thread") {} GlobalState::~GlobalState() { if (blink_platform_) { @@ -105,8 +116,8 @@ SkFontConfigInterface::SetGlobal(font_loader_.get()); #endif - ui_init_.reset( - new ui::mojo::UIInit(screen_size_in_pixels, device_pixel_ratio)); + ui_init_.reset(new ui::mojo::UIInit( + DisplaysFromSizeAndScale(screen_size_in_pixels_, device_pixel_ratio_))); base::DiscardableMemoryAllocator::SetInstance(&discardable_memory_allocator_); mojo::URLRequestPtr request(mojo::URLRequest::New());
diff --git a/components/html_viewer/html_document.cc b/components/html_viewer/html_document.cc index fd6df51..adf7cbf6 100644 --- a/components/html_viewer/html_document.cc +++ b/components/html_viewer/html_document.cc
@@ -10,6 +10,7 @@ #include "base/stl_util.h" #include "base/strings/string_util.h" #include "base/thread_task_runner_handle.h" +#include "base/time/time.h" #include "components/html_viewer/blink_url_request_type_converters.h" #include "components/html_viewer/devtools_agent_impl.h" #include "components/html_viewer/document_resource_waiter.h" @@ -18,8 +19,8 @@ #include "components/html_viewer/html_frame_tree_manager.h" #include "components/html_viewer/test_html_viewer_impl.h" #include "components/html_viewer/web_url_loader_impl.h" -#include "components/mus/public/cpp/view.h" -#include "components/mus/public/cpp/view_tree_connection.h" +#include "components/mus/public/cpp/window.h" +#include "components/mus/public/cpp/window_tree_connection.h" #include "components/mus/vm/ids.h" #include "mojo/application/public/cpp/application_impl.h" #include "mojo/application/public/cpp/connect.h" @@ -31,7 +32,7 @@ #include "ui/gfx/geometry/size.h" using mojo::AxProvider; -using mus::View; +using mus::Window; namespace html_viewer { namespace { @@ -45,28 +46,28 @@ } // namespace -// A ViewTreeDelegate implementation that delegates to a (swappable) delegate. +// A WindowTreeDelegate implementation that delegates to a (swappable) delegate. // This is used when one HTMLDocument takes over for another delegate // (OnSwap()). -class ViewTreeDelegateImpl : public mus::ViewTreeDelegate { +class WindowTreeDelegateImpl : public mus::WindowTreeDelegate { public: - explicit ViewTreeDelegateImpl(mus::ViewTreeDelegate* delegate) + explicit WindowTreeDelegateImpl(mus::WindowTreeDelegate* delegate) : delegate_(delegate) {} - ~ViewTreeDelegateImpl() override {} + ~WindowTreeDelegateImpl() override {} - void set_delegate(mus::ViewTreeDelegate* delegate) { delegate_ = delegate; } + void set_delegate(mus::WindowTreeDelegate* delegate) { delegate_ = delegate; } private: - // ViewTreeDelegate: - void OnEmbed(mus::View* root) override { delegate_->OnEmbed(root); } + // WindowTreeDelegate: + void OnEmbed(mus::Window* root) override { delegate_->OnEmbed(root); } void OnUnembed() override { delegate_->OnUnembed(); } - void OnConnectionLost(mus::ViewTreeConnection* connection) override { + void OnConnectionLost(mus::WindowTreeConnection* connection) override { delegate_->OnConnectionLost(connection); } - mus::ViewTreeDelegate* delegate_; + mus::WindowTreeDelegate* delegate_; - DISALLOW_COPY_AND_ASSIGN(ViewTreeDelegateImpl); + DISALLOW_COPY_AND_ASSIGN(WindowTreeDelegateImpl); }; HTMLDocument::BeforeLoadCache::BeforeLoadCache() {} @@ -77,17 +78,17 @@ } HTMLDocument::TransferableState::TransferableState() - : owns_view_tree_connection(false), root(nullptr) {} + : owns_window_tree_connection(false), root(nullptr) {} HTMLDocument::TransferableState::~TransferableState() {} void HTMLDocument::TransferableState::Move(TransferableState* other) { - owns_view_tree_connection = other->owns_view_tree_connection; + owns_window_tree_connection = other->owns_window_tree_connection; root = other->root; - view_tree_delegate_impl = other->view_tree_delegate_impl.Pass(); + window_tree_delegate_impl = other->window_tree_delegate_impl.Pass(); other->root = nullptr; - other->owns_view_tree_connection = false; + other->owns_window_tree_connection = false; } HTMLDocument::HTMLDocument(mojo::ApplicationImpl* html_document_app, @@ -117,7 +118,7 @@ void HTMLDocument::Destroy() { if (resource_waiter_) { - mus::View* root = resource_waiter_->root(); + mus::Window* root = resource_waiter_->root(); if (root) { resource_waiter_.reset(); delete root->connection(); @@ -130,7 +131,7 @@ frame_->Close(); } else if (transferable_state_.root) { // This triggers deleting us. - if (transferable_state_.owns_view_tree_connection) + if (transferable_state_.owns_window_tree_connection) delete transferable_state_.root->connection(); else delete this; @@ -149,7 +150,7 @@ DCHECK(resource_waiter_ && resource_waiter_->is_ready()); // Note: |view| is null if we're taking over for an existing frame. - mus::View* view = resource_waiter_->root(); + mus::Window* view = resource_waiter_->root(); if (view) { global_state_->InitIfNecessary( view->viewport_metrics().size_in_pixels.To<gfx::Size>(), @@ -160,6 +161,8 @@ extra_data->synthetic_response = resource_waiter_->ReleaseURLResponse().Pass(); + base::TimeTicks navigation_start_time = + resource_waiter_->navigation_start_time(); frame_ = HTMLFrameTreeManager::CreateFrameAndAttachToTree( global_state_, view, resource_waiter_.Pass(), this); @@ -185,7 +188,7 @@ web_request.setURL(url); web_request.setExtraData(extra_data.release()); - frame_->LoadRequest(web_request); + frame_->LoadRequest(web_request, navigation_start_time); } HTMLDocument::BeforeLoadCache* HTMLDocument::GetBeforeLoadCache() { @@ -195,12 +198,12 @@ return before_load_cache_.get(); } -void HTMLDocument::OnEmbed(View* root) { +void HTMLDocument::OnEmbed(Window* root) { transferable_state_.root = root; resource_waiter_->SetRoot(root); } -void HTMLDocument::OnConnectionLost(mus::ViewTreeConnection* connection) { +void HTMLDocument::OnConnectionLost(mus::WindowTreeConnection* connection) { delete this; } @@ -238,27 +241,27 @@ void HTMLDocument::OnSwap(HTMLFrame* frame, HTMLFrameDelegate* old_delegate) { DCHECK(frame->IsLocal()); - DCHECK(frame->view()); + DCHECK(frame->window()); DCHECK(!frame_); DCHECK(!transferable_state_.root); if (!old_delegate) { // We're taking over a child of a local root that isn't associated with a // delegate. In this case the frame's view is not the root of the - // ViewTreeConnection. - transferable_state_.owns_view_tree_connection = false; - transferable_state_.root = frame->view(); + // WindowTreeConnection. + transferable_state_.owns_window_tree_connection = false; + transferable_state_.root = frame->window(); } else { HTMLDocument* old_document = static_cast<HTMLDocument*>(old_delegate); transferable_state_.Move(&old_document->transferable_state_); - if (transferable_state_.view_tree_delegate_impl) - transferable_state_.view_tree_delegate_impl->set_delegate(this); + if (transferable_state_.window_tree_delegate_impl) + transferable_state_.window_tree_delegate_impl->set_delegate(this); old_document->frame_ = nullptr; old_document->Destroy(); } } void HTMLDocument::OnFrameDestroyed() { - if (!transferable_state_.owns_view_tree_connection) + if (!transferable_state_.owns_window_tree_connection) delete this; } @@ -312,13 +315,13 @@ void HTMLDocument::Create( mojo::ApplicationConnection* connection, mojo::InterfaceRequest<mojo::ViewTreeClient> request) { - DCHECK(!transferable_state_.view_tree_delegate_impl); - transferable_state_.view_tree_delegate_impl.reset( - new ViewTreeDelegateImpl(this)); - transferable_state_.owns_view_tree_connection = true; - mus::ViewTreeConnection::Create( - transferable_state_.view_tree_delegate_impl.get(), request.Pass(), - mus::ViewTreeConnection::CreateType::DONT_WAIT_FOR_EMBED); + DCHECK(!transferable_state_.window_tree_delegate_impl); + transferable_state_.window_tree_delegate_impl.reset( + new WindowTreeDelegateImpl(this)); + transferable_state_.owns_window_tree_connection = true; + mus::WindowTreeConnection::Create( + transferable_state_.window_tree_delegate_impl.get(), request.Pass(), + mus::WindowTreeConnection::CreateType::DONT_WAIT_FOR_EMBED); } } // namespace html_viewer
diff --git a/components/html_viewer/html_document.h b/components/html_viewer/html_document.h index 501d688..2b82384e 100644 --- a/components/html_viewer/html_document.h +++ b/components/html_viewer/html_document.h
@@ -15,7 +15,7 @@ #include "components/html_viewer/ax_provider_impl.h" #include "components/html_viewer/html_frame_delegate.h" #include "components/html_viewer/public/interfaces/test_html_viewer.mojom.h" -#include "components/mus/public/cpp/view_tree_delegate.h" +#include "components/mus/public/cpp/window_tree_delegate.h" #include "components/web_view/public/interfaces/frame.mojom.h" #include "mojo/application/public/cpp/app_lifetime_helper.h" #include "mojo/application/public/cpp/interface_factory.h" @@ -28,8 +28,8 @@ } namespace mus { -class View; -class ViewTreeConnection; +class Window; +class WindowTreeConnection; } namespace html_viewer { @@ -40,7 +40,7 @@ class HTMLFactory; class HTMLFrame; class TestHTMLViewerImpl; -class ViewTreeDelegateImpl; +class WindowTreeDelegateImpl; class WebLayerTreeViewImpl; // A view for a single HTML document. @@ -49,7 +49,7 @@ // . When the View the HTMLDocument is embedded in is destroyed. // . Explicitly by way of Destroy(). class HTMLDocument - : public mus::ViewTreeDelegate, + : public mus::WindowTreeDelegate, public HTMLFrameDelegate, public mojo::InterfaceFactory<mojo::AxProvider>, public mojo::InterfaceFactory<web_view::mojom::FrameClient>, @@ -95,9 +95,9 @@ // Takes the state from |other|. void Move(TransferableState* other); - bool owns_view_tree_connection; - mus::View* root; - scoped_ptr<ViewTreeDelegateImpl> view_tree_delegate_impl; + bool owns_window_tree_connection; + mus::Window* root; + scoped_ptr<WindowTreeDelegateImpl> window_tree_delegate_impl; }; ~HTMLDocument() override; @@ -106,9 +106,9 @@ BeforeLoadCache* GetBeforeLoadCache(); - // ViewTreeDelegate: - void OnEmbed(mus::View* root) override; - void OnConnectionLost(mus::ViewTreeConnection* connection) override; + // WindowTreeDelegate: + void OnEmbed(mus::Window* root) override; + void OnConnectionLost(mus::WindowTreeConnection* connection) override; // HTMLFrameDelegate: mojo::ApplicationImpl* GetApp() override;
diff --git a/components/html_viewer/html_frame.cc b/components/html_viewer/html_frame.cc index 980534e7..c1b084d8 100644 --- a/components/html_viewer/html_frame.cc +++ b/components/html_viewer/html_frame.cc
@@ -34,9 +34,9 @@ #include "components/html_viewer/web_layer_tree_view_impl.h" #include "components/html_viewer/web_storage_namespace_impl.h" #include "components/html_viewer/web_url_loader_impl.h" -#include "components/mus/public/cpp/scoped_view_ptr.h" -#include "components/mus/public/cpp/view.h" -#include "components/mus/public/cpp/view_tree_connection.h" +#include "components/mus/public/cpp/scoped_window_ptr.h" +#include "components/mus/public/cpp/window.h" +#include "components/mus/public/cpp/window_tree_connection.h" #include "components/mus/vm/ids.h" #include "mojo/application/public/cpp/application_impl.h" #include "mojo/application/public/cpp/connect.h" @@ -74,7 +74,6 @@ using mojo::Rect; using mojo::ServiceProviderPtr; using mojo::URLResponsePtr; -using mus::View; using web_view::mojom::HTMLMessageEvent; using web_view::mojom::HTMLMessageEventPtr; @@ -121,7 +120,7 @@ HTMLFrame::HTMLFrame(CreateParams* params) : frame_tree_manager_(params->manager), parent_(params->parent), - view_(nullptr), + window_(nullptr), id_(params->id), web_frame_(nullptr), delegate_(params->delegate), @@ -130,8 +129,8 @@ if (parent_) parent_->children_.push_back(this); - if (params->view && params->view->id() == id_) - SetView(params->view); + if (params->window && params->window->id() == id_) + SetWindow(params->window); SetReplicatedFrameStateFromClientProperties(params->properties, &state_); @@ -151,14 +150,14 @@ // The resize and setDeviceScaleFactor() needs to be after setting the main // frame. - const gfx::Size size_in_pixels(params->view->bounds().width, - params->view->bounds().height); + const gfx::Size size_in_pixels(params->window->bounds().width, + params->window->bounds().height); const gfx::Size size_in_dips = gfx::ConvertSizeToDIP( - params->view->viewport_metrics().device_pixel_ratio, size_in_pixels); + params->window->viewport_metrics().device_pixel_ratio, size_in_pixels); web_view()->resize(size_in_dips); web_frame_ = local_web_frame; web_view()->setDeviceScaleFactor(global_state()->device_pixel_ratio()); - if (id_ != params->view->id()) { + if (id_ != params->window->id()) { blink::WebRemoteFrame* remote_web_frame = blink::WebRemoteFrame::create(state_.tree_scope, this); local_web_frame->swap(remote_web_frame); @@ -182,8 +181,8 @@ startup_performance_data_collector_ = StatsCollectionController::Install(web_frame_, GetApp()); } - } else if (!params->is_local_create_child && params->view && - id_ == params->view->id()) { + } else if (!params->is_local_create_child && params->window && + id_ == params->window->id()) { // Frame represents the local frame, and it isn't the root of the tree. HTMLFrame* previous_sibling = GetPreviousSibling(this); blink::WebFrame* previous_web_frame = @@ -272,13 +271,15 @@ return false; } -void HTMLFrame::LoadRequest(const blink::WebURLRequest& request) { +void HTMLFrame::LoadRequest(const blink::WebURLRequest& request, + base::TimeTicks navigation_start_time) { DCHECK(IsLocal()); DVLOG(2) << "HTMLFrame::LoadRequest this=" << this << " id=" << id_ << " URL=" << GURL(request.url()); pending_navigation_ = false; + navigation_start_time_ = navigation_start_time; web_frame_->toWebLocalFrame()->loadRequest(request); } @@ -299,9 +300,9 @@ if (delegate_) delegate_->OnFrameDestroyed(); - if (view_) { - view_->RemoveObserver(this); - mus::ScopedViewPtr::DeleteViewOrViewManager(view_); + if (window_) { + window_->RemoveObserver(this); + mus::ScopedWindowPtr::DeleteWindowOrWindowManager(window_); } } @@ -322,10 +323,10 @@ blink::WebSandboxFlags sandbox_flags) { DCHECK(IsLocal()); // Can't create children of remote frames. DCHECK_EQ(parent, web_frame_); - DCHECK(view_); // If we're local we have to have a view. + DCHECK(window_); // If we're local we have to have a view. // Create the view that will house the frame now. We embed once we know the // url (see decidePolicyForNavigation()). - mus::View* child_view = view_->connection()->CreateView(); + mus::Window* child_view = window_->connection()->CreateWindow(); ReplicatedFrameState child_state; child_state.name = frame_name; child_state.tree_scope = scope; @@ -335,7 +336,7 @@ ClientPropertiesFromReplicatedFrameState(child_state, &client_properties); child_view->SetVisible(true); - view_->AddChild(child_view); + window_->AddChild(child_view); HTMLFrame::CreateParams params(frame_tree_manager_, this, child_view->id(), child_view, client_properties, nullptr); @@ -343,7 +344,7 @@ HTMLFrame* child_frame = GetFirstAncestorWithDelegate() ->delegate_->GetHTMLFactory() ->CreateHTMLFrame(¶ms); - child_frame->owned_view_.reset(new mus::ScopedViewPtr(child_view)); + child_frame->owned_window_.reset(new mus::ScopedWindowPtr(child_view)); web_view::mojom::FrameClientPtr client_ptr; child_frame->frame_client_binding_.reset( @@ -395,6 +396,8 @@ << " URL=" << GURL(info.urlRequest.url()); mojo::URLRequestPtr url_request = mojo::URLRequest::From(info.urlRequest); + url_request->originating_time_ticks = + base::TimeTicks::Now().ToInternalValue(); server_->RequestNavigate( WebNavigationPolicyToNavigationTarget(info.defaultPolicy), id_, url_request.Pass()); @@ -491,6 +494,13 @@ // NavigationControllerImpl::RendererDidNavigate use everything passed // through. server_->DidCommitProvisionalLoad(); + + if (!navigation_start_time_.is_null()) { + frame->dataSource()->setNavigationStartTime( + navigation_start_time_.ToInternalValue() / + static_cast<double>(base::Time::kMicrosecondsPerSecond)); + navigation_start_time_ = base::TimeTicks(); + } } void HTMLFrame::didReceiveTitle(blink::WebLocalFrame* frame, @@ -570,19 +580,19 @@ return frame_tree_manager_->local_frame_->server_.get(); } -void HTMLFrame::SetView(mus::View* view) { - if (view_) - view_->RemoveObserver(this); - view_ = view; - if (view_) - view_->AddObserver(this); +void HTMLFrame::SetWindow(mus::Window* window) { + if (window_) + window_->RemoveObserver(this); + window_ = window; + if (window_) + window_->AddObserver(this); } void HTMLFrame::CreateRootWebWidget() { DCHECK(!html_widget_); - if (view_) { + if (window_) { HTMLWidgetRootLocal::CreateParams create_params(GetApp(), global_state(), - view_); + window_); html_widget_.reset( delegate_->GetHTMLFactory()->CreateHTMLWidgetRootLocal(&create_params)); } else { @@ -594,14 +604,14 @@ DCHECK(!html_widget_); DCHECK(IsLocal()); html_widget_.reset( - new HTMLWidgetLocalRoot(GetApp(), global_state(), view_, local_frame)); + new HTMLWidgetLocalRoot(GetApp(), global_state(), window_, local_frame)); } void HTMLFrame::UpdateFocus() { blink::WebWidget* web_widget = GetWebWidget(); - if (!web_widget || !view_) + if (!web_widget || !window_) return; - const bool is_focused = view_ && view_->HasFocus(); + const bool is_focused = window_ && window_->HasFocus(); web_widget->setFocus(is_focused); if (web_widget->isWebView()) static_cast<blink::WebView*>(web_widget)->setIsActive(is_focused); @@ -621,15 +631,15 @@ // swap() ends up calling us back and we then close the frame, which deletes // it. web_frame_->swap(remote_frame); - if (owned_view_) { + if (owned_window_) { surface_layer_ = cc::SurfaceLayer::Create(cc_blink::WebLayerImpl::LayerSettings(), base::Bind(&SatisfyCallback), base::Bind(&RequireCallback)); surface_layer_->SetSurfaceId( - cc::SurfaceId(owned_view_->view()->id()), + cc::SurfaceId(owned_window_->window()->id()), global_state()->device_pixel_ratio(), - owned_view_->view()->bounds().To<gfx::Rect>().size()); + owned_window_->window()->bounds().To<gfx::Rect>().size()); web_layer_.reset(new cc_blink::WebLayerImpl(surface_layer_)); } @@ -644,7 +654,7 @@ pending_navigation_ = false; web_frame_ = remote_frame; - SetView(nullptr); + SetWindow(nullptr); server_.reset(); frame_client_binding_.reset(); if (delegate) @@ -653,14 +663,14 @@ void HTMLFrame::SwapToLocal( HTMLFrameDelegate* delegate, - mus::View* view, + mus::Window* window, const mojo::Map<mojo::String, mojo::Array<uint8_t>>& properties) { DVLOG(2) << "HTMLFrame::SwapToLocal this=" << this << " id=" << id_; CHECK(!IsLocal()); // It doesn't make sense for the root to swap to local. CHECK(parent_); delegate_ = delegate; - SetView(view); + SetWindow(window); SetReplicatedFrameStateFromClientProperties(properties, &state_); blink::WebLocalFrame* local_web_frame = blink::WebLocalFrame::create(state_.tree_scope, this); @@ -726,22 +736,23 @@ delete this; } -void HTMLFrame::OnViewBoundsChanged(View* view, - const Rect& old_bounds, - const Rect& new_bounds) { - DCHECK_EQ(view, view_); +void HTMLFrame::OnWindowBoundsChanged(mus::Window* window, + const Rect& old_bounds, + const Rect& new_bounds) { + DCHECK_EQ(window, window_); if (html_widget_) - html_widget_->OnViewBoundsChanged(view); + html_widget_->OnWindowBoundsChanged(window); } -void HTMLFrame::OnViewDestroyed(View* view) { - DCHECK_EQ(view, view_); - view_->RemoveObserver(this); - view_ = nullptr; +void HTMLFrame::OnWindowDestroyed(mus::Window* window) { + DCHECK_EQ(window, window_); + window_->RemoveObserver(this); + window_ = nullptr; Close(); } -void HTMLFrame::OnViewInputEvent(View* view, const mojo::EventPtr& event) { +void HTMLFrame::OnWindowInputEvent(mus::Window* window, + const mojo::EventPtr& event) { if (event->pointer_data && event->pointer_data->location) { // Blink expects coordintes to be in DIPs. event->pointer_data->location->x /= global_state()->device_pixel_ratio(); @@ -776,16 +787,17 @@ web_widget->handleInputEvent(*web_event); } -void HTMLFrame::OnViewFocusChanged(mus::View* gained_focus, - mus::View* lost_focus) { +void HTMLFrame::OnWindowFocusChanged(mus::Window* gained_focus, + mus::Window* lost_focus) { UpdateFocus(); } void HTMLFrame::OnConnect(web_view::mojom::FramePtr frame, uint32_t change_id, - uint32_t view_id, - web_view::mojom::ViewConnectType view_connect_type, + uint32_t window_id, + web_view::mojom::ViewConnectType window_connect_type, mojo::Array<web_view::mojom::FrameDataPtr> frame_data, + int64_t navigation_start_time_ticks, const OnConnectCallback& callback) { // This is called if this frame is created by way of OnCreatedFrame(). callback.Run(); @@ -981,7 +993,7 @@ const gfx::Rect rect_in_pixels(gfx::ConvertRectToPixel( global_state()->device_pixel_ratio(), rect_in_dip)); const mojo::RectPtr mojo_rect_in_pixels(mojo::Rect::From(rect_in_pixels)); - view_->SetBounds(*mojo_rect_in_pixels); + window_->SetBounds(*mojo_rect_in_pixels); } void HTMLFrame::navigate(const blink::WebURLRequest& request, @@ -1000,7 +1012,7 @@ void HTMLFrame::frameRectsChanged(const blink::WebRect& frame_rect) { // Only the owner of view can update its size. - if (!owned_view_) + if (!owned_window_) return; const gfx::Rect rect_in_dip(frame_rect.x, frame_rect.y, frame_rect.width, @@ -1008,15 +1020,15 @@ const gfx::Rect rect_in_pixels(gfx::ConvertRectToPixel( global_state()->device_pixel_ratio(), rect_in_dip)); const mojo::RectPtr mojo_rect_in_pixels(mojo::Rect::From(rect_in_pixels)); - owned_view_->view()->SetBounds(*mojo_rect_in_pixels); + owned_window_->window()->SetBounds(*mojo_rect_in_pixels); if (!surface_layer_) return; surface_layer_->SetSurfaceId( - cc::SurfaceId(owned_view_->view()->id()), + cc::SurfaceId(owned_window_->window()->id()), global_state()->device_pixel_ratio(), - owned_view_->view()->bounds().To<gfx::Rect>().size()); + owned_window_->window()->bounds().To<gfx::Rect>().size()); } } // namespace mojo
diff --git a/components/html_viewer/html_frame.h b/components/html_viewer/html_frame.h index 2003bcc..e444f67 100644 --- a/components/html_viewer/html_frame.h +++ b/components/html_viewer/html_frame.h
@@ -9,10 +9,11 @@ #include "base/basictypes.h" #include "base/memory/scoped_ptr.h" +#include "base/time/time.h" #include "cc/layers/surface_layer.h" #include "components/html_viewer/html_frame_tree_manager.h" #include "components/html_viewer/replicated_frame_state.h" -#include "components/mus/public/cpp/view_observer.h" +#include "components/mus/public/cpp/window_observer.h" #include "components/web_view/public/interfaces/frame.mojom.h" #include "mojo/services/tracing/public/interfaces/tracing.mojom.h" #include "third_party/WebKit/public/platform/WebURLRequest.h" @@ -37,8 +38,8 @@ } namespace mus { -class ScopedViewPtr; -class View; +class ScopedWindowPtr; +class Window; } namespace html_viewer { @@ -69,20 +70,20 @@ class HTMLFrame : public blink::WebFrameClient, public blink::WebRemoteFrameClient, public web_view::mojom::FrameClient, - public mus::ViewObserver { + public mus::WindowObserver { public: struct CreateParams { CreateParams( HTMLFrameTreeManager* manager, HTMLFrame* parent, uint32_t id, - mus::View* view, + mus::Window* window, const mojo::Map<mojo::String, mojo::Array<uint8_t>>& properties, HTMLFrameDelegate* delegate) : manager(manager), parent(parent), id(id), - view(view), + window(window), properties(properties), delegate(delegate), is_local_create_child(false) {} @@ -91,7 +92,7 @@ HTMLFrameTreeManager* manager; HTMLFrame* parent; uint32_t id; - mus::View* view; + mus::Window* window; const mojo::Map<mojo::String, mojo::Array<uint8_t>>& properties; HTMLFrameDelegate* delegate; @@ -133,7 +134,7 @@ // The mus::View this frame renders to. This is non-null for the local frame // the frame tree was created with as well as non-null for any frames created // locally. - mus::View* view() { return view_; } + mus::Window* window() { return window_; } HTMLFrameTreeManager* frame_tree_manager() { return frame_tree_manager_; } @@ -147,7 +148,8 @@ // Returns true if this or one of the frames descendants is local. bool HasLocalDescendant() const; - void LoadRequest(const blink::WebURLRequest& request); + void LoadRequest(const blink::WebURLRequest& request, + base::TimeTicks navigation_start_time); protected: virtual ~HTMLFrame(); @@ -226,7 +228,7 @@ // Gets the server Frame to use for this frame. web_view::mojom::Frame* GetServerFrame(); - void SetView(mus::View* view); + void SetWindow(mus::Window* window); // Creates the appropriate WebWidget implementation for the Frame. void CreateRootWebWidget(); @@ -241,7 +243,7 @@ // Swaps this frame from a remote frame to a local frame. void SwapToLocal( HTMLFrameDelegate* delegate, - mus::View* view, + mus::Window* window, const mojo::Map<mojo::String, mojo::Array<uint8_t>>& properties); // Invoked when changing the delegate. This informs the new delegate to take @@ -261,21 +263,23 @@ // The various frameDetached() implementations call into this. void FrameDetachedImpl(blink::WebFrame* web_frame); - // mus::ViewObserver methods: - void OnViewBoundsChanged(mus::View* view, - const mojo::Rect& old_bounds, - const mojo::Rect& new_bounds) override; - void OnViewDestroyed(mus::View* view) override; - void OnViewInputEvent(mus::View* view, const mojo::EventPtr& event) override; - void OnViewFocusChanged(mus::View* gained_focus, - mus::View* lost_focus) override; + // mus::WindowObserver methods: + void OnWindowBoundsChanged(mus::Window* window, + const mojo::Rect& old_bounds, + const mojo::Rect& new_bounds) override; + void OnWindowDestroyed(mus::Window* window) override; + void OnWindowInputEvent(mus::Window* window, + const mojo::EventPtr& event) override; + void OnWindowFocusChanged(mus::Window* gained_focus, + mus::Window* lost_focus) override; // web_view::mojom::FrameClient: void OnConnect(web_view::mojom::FramePtr server, uint32_t change_id, - uint32_t view_id, + uint32_t window_id, web_view::mojom::ViewConnectType view_connect_type, mojo::Array<web_view::mojom::FrameDataPtr> frame_data, + int64_t navigation_start_time_ticks, const OnConnectCallback& callback) override; void OnFrameAdded(uint32_t change_id, web_view::mojom::FrameDataPtr frame_data) override; @@ -320,7 +324,7 @@ HTMLFrame* parent_; // |view_| is non-null for local frames or remote frames that were once // local. - mus::View* view_; + mus::Window* window_; // The id for this frame. If there is a view, this is the same id as the // view has. const uint32_t id_; @@ -340,16 +344,16 @@ ReplicatedFrameState state_; // If this frame is the result of creating a local frame - // (createChildFrame()), then |owned_view_| is the View initially created - // for the frame. While the frame is local |owned_view_| is the same as + // (createChildFrame()), then |owned_window_| is the View initially created + // for the frame. While the frame is local |owned_window_| is the same as // |view_|. If this frame becomes remote |view_| is set to null and - // |owned_view_| remains as the View initially created for the frame. + // |owned_window_| remains as the View initially created for the frame. // // This is done to ensure the View isn't prematurely deleted (it must exist // as long as the frame is valid). If the View was deleted as soon as the // frame was swapped to remote then the process rendering to the view would // be severed. - scoped_ptr<mus::ScopedViewPtr> owned_view_; + scoped_ptr<mus::ScopedWindowPtr> owned_window_; // This object is only valid in the context of performance tests. tracing::StartupPerformanceDataCollectorPtr @@ -361,6 +365,8 @@ // received response to it. bool pending_navigation_; + base::TimeTicks navigation_start_time_; + base::WeakPtrFactory<HTMLFrame> weak_factory_; DISALLOW_COPY_AND_ASSIGN(HTMLFrame);
diff --git a/components/html_viewer/html_frame_apptest.cc b/components/html_viewer/html_frame_apptest.cc index 4bfc034..d7302be4 100644 --- a/components/html_viewer/html_frame_apptest.cc +++ b/components/html_viewer/html_frame_apptest.cc
@@ -10,11 +10,12 @@ #include "base/run_loop.h" #include "base/strings/stringprintf.h" #include "base/test/test_timeouts.h" +#include "base/time/time.h" #include "base/values.h" #include "components/html_viewer/public/interfaces/test_html_viewer.mojom.h" -#include "components/mus/public/cpp/tests/view_manager_test_base.h" -#include "components/mus/public/cpp/view.h" -#include "components/mus/public/cpp/view_tree_connection.h" +#include "components/mus/public/cpp/tests/window_server_test_base.h" +#include "components/mus/public/cpp/window.h" +#include "components/mus/public/cpp/window_tree_connection.h" #include "components/web_view/frame.h" #include "components/web_view/frame_connection.h" #include "components/web_view/frame_tree.h" @@ -24,7 +25,7 @@ #include "net/test/spawned_test_server/spawned_test_server.h" #include "third_party/mojo_services/src/accessibility/public/interfaces/accessibility.mojom.h" -using mus::ViewManagerTestBase; +using mus::WindowServerTestBase; using web_view::Frame; using web_view::FrameConnection; using web_view::FrameTree; @@ -42,7 +43,7 @@ void OnGotContentHandlerForRoot(bool* got_callback) { *got_callback = true; - ignore_result(ViewManagerTestBase::QuitRunLoop()); + ignore_result(WindowServerTestBase::QuitRunLoop()); } mojo::ApplicationConnection* ApplicationConnectionForFrame(Frame* frame) { @@ -56,9 +57,9 @@ std::string result; test_html_viewer->GetContentAsText([&result](const String& mojo_string) { result = mojo_string; - ASSERT_TRUE(ViewManagerTestBase::QuitRunLoop()); + ASSERT_TRUE(WindowServerTestBase::QuitRunLoop()); }); - if (!ViewManagerTestBase::DoRunLoopWithTimeout()) + if (!WindowServerTestBase::DoRunLoopWithTimeout()) ADD_FAILURE() << "Timed out waiting for execute to complete"; // test_html_viewer.WaitForIncomingResponse(); return result; @@ -71,9 +72,9 @@ scoped_ptr<base::Value> result; test_html_viewer->ExecuteScript(script, [&result](const String& json_string) { result = base::JSONReader::Read(json_string.To<std::string>()); - ASSERT_TRUE(ViewManagerTestBase::QuitRunLoop()); + ASSERT_TRUE(WindowServerTestBase::QuitRunLoop()); }); - if (!ViewManagerTestBase::DoRunLoopWithTimeout()) + if (!WindowServerTestBase::DoRunLoopWithTimeout()) ADD_FAILURE() << "Timed out waiting for execute to complete"; return result.Pass(); } @@ -99,7 +100,7 @@ waiting_for_frame_child_count_->frame = frame; waiting_for_frame_child_count_->count = count; - return ViewManagerTestBase::DoRunLoopWithTimeout(); + return WindowServerTestBase::DoRunLoopWithTimeout(); } // Returns true if |frame| has navigated. If |frame| hasn't navigated runs @@ -109,7 +110,7 @@ return true; frames_waiting_for_navigate_.insert(frame); - return ViewManagerTestBase::DoRunLoopWithTimeout(); + return WindowServerTestBase::DoRunLoopWithTimeout(); } // TestFrameTreeDelegate: @@ -120,12 +121,12 @@ DidChildNavigate(waiting_for_frame_child_count_->frame, waiting_for_frame_child_count_->count)) { waiting_for_frame_child_count_.reset(); - ASSERT_TRUE(ViewManagerTestBase::QuitRunLoop()); + ASSERT_TRUE(WindowServerTestBase::QuitRunLoop()); } if (frames_waiting_for_navigate_.count(frame)) { frames_waiting_for_navigate_.erase(frame); - ignore_result(ViewManagerTestBase::QuitRunLoop()); + ignore_result(WindowServerTestBase::QuitRunLoop()); } } @@ -158,7 +159,7 @@ } // namespace -class HTMLFrameTest : public ViewManagerTestBase { +class HTMLFrameTest : public WindowServerTestBase { public: HTMLFrameTest() {} ~HTMLFrameTest() override {} @@ -167,11 +168,11 @@ // Creates the frame tree showing an empty page at the root and adds (via // script) a frame showing the same empty page. Frame* LoadEmptyPageAndCreateFrame() { - mus::View* embed_view = window_manager()->CreateView(); + mus::Window* embed_window = window_manager()->CreateWindow(); frame_tree_delegate_.reset( new TestFrameTreeDelegateImpl(application_impl())); - FrameConnection* root_connection = - InitFrameTree(embed_view, "http://127.0.0.1:%u/files/empty_page2.html"); + FrameConnection* root_connection = InitFrameTree( + embed_window, "http://127.0.0.1:%u/files/empty_page2.html"); if (!root_connection) { ADD_FAILURE() << "unable to establish root connection"; return nullptr; @@ -211,7 +212,7 @@ return request.Pass(); } - FrameConnection* InitFrameTree(mus::View* view, + FrameConnection* InitFrameTree(mus::Window* view, const std::string& url_string) { frame_tree_delegate_.reset( new TestFrameTreeDelegateImpl(application_impl())); @@ -220,23 +221,23 @@ frame_connection->Init( application_impl(), BuildRequestForURL(url_string), base::Bind(&OnGotContentHandlerForRoot, &got_callback)); - ignore_result(ViewManagerTestBase::DoRunLoopWithTimeout()); + ignore_result(WindowServerTestBase::DoRunLoopWithTimeout()); if (!got_callback) return nullptr; FrameConnection* result = frame_connection.get(); FrameClient* frame_client = frame_connection->frame_client(); ViewTreeClientPtr tree_client = frame_connection->GetViewTreeClient(); - frame_tree_.reset( - new FrameTree(result->GetContentHandlerID(), view, tree_client.Pass(), - frame_tree_delegate_.get(), frame_client, - frame_connection.Pass(), Frame::ClientPropertyMap())); + frame_tree_.reset(new FrameTree( + result->GetContentHandlerID(), view, tree_client.Pass(), + frame_tree_delegate_.get(), frame_client, frame_connection.Pass(), + Frame::ClientPropertyMap(), base::TimeTicks::Now())); frame_tree_delegate_->set_frame_tree(frame_tree_.get()); return result; } // ViewManagerTest: void SetUp() override { - ViewManagerTestBase::SetUp(); + WindowServerTestBase::SetUp(); // Start a test server. http_server_.reset(new net::SpawnedTestServer( @@ -247,7 +248,7 @@ void TearDown() override { frame_tree_.reset(); http_server_.reset(); - ViewManagerTestBase::TearDown(); + WindowServerTestBase::TearDown(); } scoped_ptr<net::SpawnedTestServer> http_server_; @@ -260,10 +261,10 @@ }; TEST_F(HTMLFrameTest, PageWithSingleFrame) { - mus::View* embed_view = window_manager()->CreateView(); + mus::Window* embed_window = window_manager()->CreateWindow(); FrameConnection* root_connection = InitFrameTree( - embed_view, "http://127.0.0.1:%u/files/page_with_single_frame.html"); + embed_window, "http://127.0.0.1:%u/files/page_with_single_frame.html"); ASSERT_TRUE(root_connection); ASSERT_EQ("Page with single frame", @@ -272,9 +273,9 @@ ASSERT_NO_FATAL_FAILURE( frame_tree_delegate_->WaitForChildFrameCount(frame_tree_->root(), 1u)); - ASSERT_EQ(1u, embed_view->children().size()); + ASSERT_EQ(1u, embed_window->children().size()); Frame* child_frame = - frame_tree_->root()->FindFrame(embed_view->children()[0]->id()); + frame_tree_->root()->FindFrame(embed_window->children()[0]->id()); ASSERT_TRUE(child_frame); ASSERT_EQ("child", @@ -285,10 +286,10 @@ // Creates two frames. The parent navigates the child frame by way of changing // the location of the child frame. TEST_F(HTMLFrameTest, ChangeLocationOfChildFrame) { - mus::View* embed_view = window_manager()->CreateView(); + mus::Window* embed_window = window_manager()->CreateWindow(); ASSERT_TRUE(InitFrameTree( - embed_view, "http://127.0.0.1:%u/files/page_with_single_frame.html")); + embed_window, "http://127.0.0.1:%u/files/page_with_single_frame.html")); // page_with_single_frame contains a child frame. The child frame should // create a new View and Frame.
diff --git a/components/html_viewer/html_frame_tree_manager.cc b/components/html_viewer/html_frame_tree_manager.cc index 2cefb66..e56a9a29 100644 --- a/components/html_viewer/html_frame_tree_manager.cc +++ b/components/html_viewer/html_frame_tree_manager.cc
@@ -16,7 +16,7 @@ #include "components/html_viewer/html_frame.h" #include "components/html_viewer/html_frame_delegate.h" #include "components/html_viewer/html_frame_tree_manager_observer.h" -#include "components/mus/public/cpp/view_tree_connection.h" +#include "components/mus/public/cpp/window_tree_connection.h" #include "components/web_view/web_view_switches.h" #include "third_party/WebKit/public/web/WebLocalFrame.h" #include "third_party/WebKit/public/web/WebRemoteFrame.h" @@ -69,7 +69,7 @@ // static HTMLFrame* HTMLFrameTreeManager::CreateFrameAndAttachToTree( GlobalState* global_state, - mus::View* view, + mus::Window* window, scoped_ptr<DocumentResourceWaiter> resource_waiter, HTMLFrameDelegate* delegate) { if (!instances_) @@ -79,11 +79,11 @@ web_view::mojom::FramePtr server_frame; mojo::Array<web_view::mojom::FrameDataPtr> frame_data; uint32_t change_id; - uint32_t view_id; + uint32_t window_id; web_view::mojom::ViewConnectType view_connect_type; web_view::mojom::FrameClient::OnConnectCallback on_connect_callback; resource_waiter->Release(&frame_client_request, &server_frame, &frame_data, - &change_id, &view_id, &view_connect_type, + &change_id, &window_id, &view_connect_type, &on_connect_callback); resource_waiter.reset(); @@ -98,7 +98,7 @@ << " frame_tree=" << frame_tree << " use_existing=" << (view_connect_type == web_view::mojom::VIEW_CONNECT_TYPE_USE_EXISTING) - << " frame_id=" << view_id; + << " frame_id=" << window_id; if (view_connect_type == web_view::mojom::VIEW_CONNECT_TYPE_USE_EXISTING && !frame_tree) { DVLOG(1) << "was told to use existing view but do not have frame tree"; @@ -107,11 +107,11 @@ if (!frame_tree) { frame_tree = new HTMLFrameTreeManager(global_state); - frame_tree->Init(delegate, view, frame_data, change_id); + frame_tree->Init(delegate, window, frame_data, change_id); (*instances_)[frame_data[0]->frame_id] = frame_tree; } else if (view_connect_type == web_view::mojom::VIEW_CONNECT_TYPE_USE_EXISTING) { - HTMLFrame* existing_frame = frame_tree->root_->FindFrame(view_id); + HTMLFrame* existing_frame = frame_tree->root_->FindFrame(window_id); if (!existing_frame) { DVLOG(1) << "was told to use existing view but could not find view"; return nullptr; @@ -123,14 +123,14 @@ existing_frame->SwapDelegate(delegate); } else { // We're going to share a frame tree. We should know about the frame. - CHECK(view->id() != frame_data[0]->frame_id); - HTMLFrame* existing_frame = frame_tree->root_->FindFrame(view->id()); + CHECK(window->id() != frame_data[0]->frame_id); + HTMLFrame* existing_frame = frame_tree->root_->FindFrame(window->id()); if (existing_frame) { CHECK(!existing_frame->IsLocal()); size_t frame_data_index = 0u; - CHECK(FindFrameDataIndex(frame_data, view->id(), &frame_data_index)); + CHECK(FindFrameDataIndex(frame_data, window->id(), &frame_data_index)); const web_view::mojom::FrameDataPtr& data = frame_data[frame_data_index]; - existing_frame->SwapToLocal(delegate, view, data->client_properties); + existing_frame->SwapToLocal(delegate, window, data->client_properties); } else { // If we can't find the frame and the change_id of the incoming // tree is before the change id we've processed, then we removed the @@ -139,7 +139,7 @@ return nullptr; // We removed the frame but it hasn't been acked yet. - if (frame_tree->pending_remove_ids_.count(view->id())) + if (frame_tree->pending_remove_ids_.count(window->id())) return nullptr; // We don't know about the frame, but should. Something is wrong. @@ -148,7 +148,7 @@ } } - HTMLFrame* frame = frame_tree->root_->FindFrame(view_id); + HTMLFrame* frame = frame_tree->root_->FindFrame(window_id); DCHECK(frame); frame->Bind(server_frame.Pass(), frame_client_request.Pass()); return frame; @@ -219,12 +219,13 @@ void HTMLFrameTreeManager::Init( HTMLFrameDelegate* delegate, - mus::View* local_view, + mus::Window* local_window, const mojo::Array<web_view::mojom::FrameDataPtr>& frame_data, uint32_t change_id) { change_id_ = change_id; - root_ = BuildFrameTree(delegate, frame_data, local_view->id(), local_view); - local_frame_ = root_->FindFrame(local_view->id()); + root_ = + BuildFrameTree(delegate, frame_data, local_window->id(), local_window); + local_frame_ = root_->FindFrame(local_window->id()); CHECK(local_frame_); local_frame_->UpdateFocus(); } @@ -233,7 +234,7 @@ HTMLFrameDelegate* delegate, const mojo::Array<web_view::mojom::FrameDataPtr>& frame_data, uint32_t local_frame_id, - mus::View* local_view) { + mus::Window* local_window) { std::vector<HTMLFrame*> parents; HTMLFrame* root = nullptr; HTMLFrame* last_frame = nullptr; @@ -246,7 +247,7 @@ } HTMLFrame::CreateParams params(this, !parents.empty() ? parents.back() : nullptr, - frame_data[i]->frame_id, local_view, + frame_data[i]->frame_id, local_window, frame_data[i]->client_properties, nullptr); if (frame_data[i]->frame_id == local_frame_id) params.delegate = delegate; @@ -347,7 +348,7 @@ return; } - // Requests to remove local frames are followed by the View being destroyed. + // Requests to remove local frames are followed by the Window being destroyed. // We handle destruction there. if (frame->IsLocal()) return;
diff --git a/components/html_viewer/html_frame_tree_manager.h b/components/html_viewer/html_frame_tree_manager.h index 8ece76d..ef6451b4 100644 --- a/components/html_viewer/html_frame_tree_manager.h +++ b/components/html_viewer/html_frame_tree_manager.h
@@ -19,7 +19,7 @@ } namespace mus { -class View; +class Window; } namespace html_viewer { @@ -34,7 +34,7 @@ // document. Some of the frames may be remote. HTMLFrameTreeManager updates its // state in response to changes from the server Frame, as well as changes // from the underlying frames. The frame tree has at least one local frame -// that is backed by a mus::View. +// that is backed by a mus::Window. class HTMLFrameTreeManager { public: // Returns a new HTMLFrame or null if a HTMLFrame does not need to be created. @@ -42,7 +42,7 @@ // Close() when done. static HTMLFrame* CreateFrameAndAttachToTree( GlobalState* global_state, - mus::View* view, + mus::Window* window, scoped_ptr<DocumentResourceWaiter> resource_waiter, HTMLFrameDelegate* delegate); @@ -71,7 +71,7 @@ ~HTMLFrameTreeManager(); void Init(HTMLFrameDelegate* delegate, - mus::View* local_view, + mus::Window* local_window, const mojo::Array<web_view::mojom::FrameDataPtr>& frame_data, uint32_t change_id); @@ -80,7 +80,7 @@ HTMLFrameDelegate* delegate, const mojo::Array<web_view::mojom::FrameDataPtr>& frame_data, uint32_t local_frame_id, - mus::View* local_view); + mus::Window* local_window); // Returns this HTMLFrameTreeManager from |instances_|. void RemoveFromInstances();
diff --git a/components/html_viewer/html_widget.cc b/components/html_viewer/html_widget.cc index 14c04742..0f34f76 100644 --- a/components/html_viewer/html_widget.cc +++ b/components/html_viewer/html_widget.cc
@@ -10,7 +10,7 @@ #include "components/html_viewer/stats_collection_controller.h" #include "components/html_viewer/web_layer_tree_view_impl.h" #include "components/html_viewer/web_storage_namespace_impl.h" -#include "components/mus/public/cpp/view.h" +#include "components/mus/public/cpp/window.h" #include "mojo/application/public/cpp/application_impl.h" #include "mojo/services/tracing/public/interfaces/tracing.mojom.h" #include "third_party/WebKit/public/web/WebFrameWidget.h" @@ -33,22 +33,23 @@ void InitializeWebLayerTreeView(WebLayerTreeViewImpl* web_layer_tree_view, mojo::ApplicationImpl* app, - mus::View* view, + mus::Window* window, blink::WebWidget* widget) { - DCHECK(view); + DCHECK(window); mojo::URLRequestPtr request(mojo::URLRequest::New()); request->url = mojo::String::From("mojo:mus"); mojo::GpuPtr gpu_service; app->ConnectToService(request.Pass(), &gpu_service); - web_layer_tree_view->Initialize(gpu_service.Pass(), view, widget); + web_layer_tree_view->Initialize(gpu_service.Pass(), window, widget); } -void UpdateWebViewSizeFromViewSize(mus::View* view, +void UpdateWebViewSizeFromViewSize(mus::Window* window, blink::WebWidget* web_widget, WebLayerTreeViewImpl* web_layer_tree_view) { - const gfx::Size size_in_pixels(view->bounds().width, view->bounds().height); + const gfx::Size size_in_pixels(window->bounds().width, + window->bounds().height); const gfx::Size size_in_dips = gfx::ConvertSizeToDIP( - view->viewport_metrics().device_pixel_ratio, size_in_pixels); + window->viewport_metrics().device_pixel_ratio, size_in_pixels); web_widget->resize( blink::WebSize(size_in_dips.width(), size_in_dips.height())); web_layer_tree_view->setViewportSize(size_in_pixels); @@ -90,31 +91,31 @@ return web_view_; } -void HTMLWidgetRootRemote::OnViewBoundsChanged(mus::View* view) {} +void HTMLWidgetRootRemote::OnWindowBoundsChanged(mus::Window* window) {} // HTMLWidgetRootLocal -------------------------------------------------------- HTMLWidgetRootLocal::CreateParams::CreateParams(mojo::ApplicationImpl* app, GlobalState* global_state, - mus::View* view) - : app(app), global_state(global_state), view(view) {} + mus::Window* window) + : app(app), global_state(global_state), window(window) {} HTMLWidgetRootLocal::CreateParams::~CreateParams() {} HTMLWidgetRootLocal::HTMLWidgetRootLocal(CreateParams* create_params) : app_(create_params->app), global_state_(create_params->global_state), - view_(create_params->view), + window_(create_params->window), web_view_(nullptr) { web_view_ = blink::WebView::create(this); - ime_controller_.reset(new ImeController(view_, web_view_)); + ime_controller_.reset(new ImeController(window_, web_view_)); // Creating the widget calls initializeLayerTreeView() to create the // |web_layer_tree_view_impl_|. As we haven't yet assigned the |web_view_| // we have to set it here. if (web_layer_tree_view_impl_) { - InitializeWebLayerTreeView(web_layer_tree_view_impl_.get(), app_, view_, + InitializeWebLayerTreeView(web_layer_tree_view_impl_.get(), app_, window_, web_view_); - UpdateWebViewSizeFromViewSize(view_, web_view_, + UpdateWebViewSizeFromViewSize(window_, web_view_, web_layer_tree_view_impl_.get()); } ConfigureSettings(web_view_->settings()); @@ -169,8 +170,8 @@ return web_view_; } -void HTMLWidgetRootLocal::OnViewBoundsChanged(mus::View* view) { - UpdateWebViewSizeFromViewSize(view, web_view_, +void HTMLWidgetRootLocal::OnWindowBoundsChanged(mus::Window* window) { + UpdateWebViewSizeFromViewSize(window, web_view_, web_layer_tree_view_impl_.get()); } @@ -178,19 +179,19 @@ HTMLWidgetLocalRoot::HTMLWidgetLocalRoot(mojo::ApplicationImpl* app, GlobalState* global_state, - mus::View* view, + mus::Window* window, blink::WebLocalFrame* web_local_frame) : app_(app), global_state_(global_state), web_frame_widget_(nullptr) { web_frame_widget_ = blink::WebFrameWidget::create(this, web_local_frame); - ime_controller_.reset(new ImeController(view, web_frame_widget_)); + ime_controller_.reset(new ImeController(window, web_frame_widget_)); // Creating the widget calls initializeLayerTreeView() to create the // |web_layer_tree_view_impl_|. As we haven't yet assigned the // |web_frame_widget_| // we have to set it here. if (web_layer_tree_view_impl_) { - InitializeWebLayerTreeView(web_layer_tree_view_impl_.get(), app_, view, + InitializeWebLayerTreeView(web_layer_tree_view_impl_.get(), app_, window, web_frame_widget_); - UpdateWebViewSizeFromViewSize(view, web_frame_widget_, + UpdateWebViewSizeFromViewSize(window, web_frame_widget_, web_layer_tree_view_impl_.get()); } } @@ -201,8 +202,8 @@ return web_frame_widget_; } -void HTMLWidgetLocalRoot::OnViewBoundsChanged(mus::View* view) { - UpdateWebViewSizeFromViewSize(view, web_frame_widget_, +void HTMLWidgetLocalRoot::OnWindowBoundsChanged(mus::Window* window) { + UpdateWebViewSizeFromViewSize(window, web_frame_widget_, web_layer_tree_view_impl_.get()); }
diff --git a/components/html_viewer/html_widget.h b/components/html_viewer/html_widget.h index 21f7daa..88a2b11c 100644 --- a/components/html_viewer/html_widget.h +++ b/components/html_viewer/html_widget.h
@@ -17,7 +17,7 @@ } namespace mus { -class View; +class Window; } namespace html_viewer { @@ -34,7 +34,7 @@ virtual blink::WebWidget* GetWidget() = 0; - virtual void OnViewBoundsChanged(mus::View* view) = 0; + virtual void OnWindowBoundsChanged(mus::Window* window) = 0; }; // Used for the root frame when the root frame is remote. @@ -50,7 +50,7 @@ // HTMLWidget: blink::WebWidget* GetWidget() override; - void OnViewBoundsChanged(mus::View* view) override; + void OnWindowBoundsChanged(mus::Window* window) override; blink::WebView* web_view_; @@ -64,12 +64,12 @@ struct CreateParams { CreateParams(mojo::ApplicationImpl* app, GlobalState* global_state, - mus::View* view); + mus::Window* window); ~CreateParams(); mojo::ApplicationImpl* app; GlobalState* global_state; - mus::View* view; + mus::Window* window; }; HTMLWidgetRootLocal(CreateParams* create_params); @@ -92,11 +92,11 @@ private: // HTMLWidget: blink::WebWidget* GetWidget() override; - void OnViewBoundsChanged(mus::View* view) override; + void OnWindowBoundsChanged(mus::Window* window) override; mojo::ApplicationImpl* app_; GlobalState* global_state_; - mus::View* view_; + mus::Window* window_; blink::WebView* web_view_; scoped_ptr<WebLayerTreeViewImpl> web_layer_tree_view_impl_; scoped_ptr<ImeController> ime_controller_; @@ -109,14 +109,14 @@ public: HTMLWidgetLocalRoot(mojo::ApplicationImpl* app, GlobalState* global_state, - mus::View* view, + mus::Window* window, blink::WebLocalFrame* web_local_frame); ~HTMLWidgetLocalRoot() override; private: // HTMLWidget: blink::WebWidget* GetWidget() override; - void OnViewBoundsChanged(mus::View* view) override; + void OnWindowBoundsChanged(mus::Window* window) override; // WebWidgetClient: virtual void initializeLayerTreeView();
diff --git a/components/html_viewer/ime_controller.cc b/components/html_viewer/ime_controller.cc index 9fe06b3..3b65a5a 100644 --- a/components/html_viewer/ime_controller.cc +++ b/components/html_viewer/ime_controller.cc
@@ -6,14 +6,14 @@ #include "components/html_viewer/blink_input_events_type_converters.h" #include "components/html_viewer/blink_text_input_type_converters.h" -#include "components/mus/public/cpp/view.h" +#include "components/mus/public/cpp/window.h" #include "third_party/WebKit/public/web/WebInputEvent.h" #include "third_party/WebKit/public/web/WebWidget.h" namespace html_viewer { -ImeController::ImeController(mus::View* view, blink::WebWidget* widget) - : view_(view), widget_(widget) {} +ImeController::ImeController(mus::Window* window, blink::WebWidget* widget) + : window_(window), widget_(widget) {} ImeController::~ImeController() {} @@ -65,9 +65,9 @@ state->composition_start = new_info.compositionStart; state->composition_end = new_info.compositionEnd; if (show_ime) - view_->SetImeVisibility(true, state.Pass()); + window_->SetImeVisibility(true, state.Pass()); else - view_->SetTextInputState(state.Pass()); + window_->SetTextInputState(state.Pass()); } }
diff --git a/components/html_viewer/ime_controller.h b/components/html_viewer/ime_controller.h index 24923ab2..740b5c5 100644 --- a/components/html_viewer/ime_controller.h +++ b/components/html_viewer/ime_controller.h
@@ -13,7 +13,7 @@ } namespace mus { -class View; +class Window; } namespace html_viewer { @@ -22,7 +22,7 @@ // handling IME related stuff. class ImeController { public: - ImeController(mus::View* view, blink::WebWidget* widget); + ImeController(mus::Window* window, blink::WebWidget* widget); ~ImeController(); // Methods called by WebWidget overrides. @@ -33,13 +33,13 @@ void ShowImeIfNeeded(); private: - // Update text input state from WebWidget to mus::View. If the focused + // Update text input state from WebWidget to mus::Window. If the focused // element is editable and |show_ime| is True, the software keyboard will be // shown. void UpdateTextInputState(bool show_ime); // Not owned objects. - mus::View* view_; + mus::Window* window_; blink::WebWidget* widget_; blink::WebTextInputInfo text_input_info_;
diff --git a/components/html_viewer/layout_test_content_handler_impl.cc b/components/html_viewer/layout_test_content_handler_impl.cc index a76f294..169adae 100644 --- a/components/html_viewer/layout_test_content_handler_impl.cc +++ b/components/html_viewer/layout_test_content_handler_impl.cc
@@ -80,7 +80,7 @@ HTMLFrame::CreateParams* params) { // The test harness isn't correctly set-up for iframes yet. So return a normal // HTMLFrame for iframes. - if (params->parent || !params->view || params->view->id() != params->id) + if (params->parent || !params->window || params->window->id() != params->id) return new HTMLFrame(params); using ProxyType =
diff --git a/components/html_viewer/layout_test_html_viewer.cc b/components/html_viewer/layout_test_html_viewer.cc index 6827feb3..3c0a72dd1 100644 --- a/components/html_viewer/layout_test_html_viewer.cc +++ b/components/html_viewer/layout_test_html_viewer.cc
@@ -8,6 +8,7 @@ #include "components/html_viewer/layout_test_content_handler_impl.h" #include "components/test_runner/web_test_interfaces.h" #include "components/web_view/test_runner/public/interfaces/layout_test_runner.mojom.h" +#include "v8/include/v8.h" namespace html_viewer { @@ -26,6 +27,10 @@ test_delegate_.set_completion_callback( base::Bind(&LayoutTestHTMLViewer::TestFinished, base::Unretained(this))); test_interfaces_->SetDelegate(&test_delegate_); + + // Always expose GC to layout tests. + std::string flags("--expose-gc"); + v8::V8::SetFlagsFromString(flags.c_str(), static_cast<int>(flags.size())); } void LayoutTestHTMLViewer::TestFinished() {
diff --git a/components/html_viewer/run_all_unittests.cc b/components/html_viewer/run_all_unittests.cc index 537e378..9a208e1 100644 --- a/components/html_viewer/run_all_unittests.cc +++ b/components/html_viewer/run_all_unittests.cc
@@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <vector> + #include "base/at_exit.h" #include "base/bind.h" #include "base/path_service.h" @@ -9,6 +11,7 @@ #include "base/test/test_suite.h" #include "third_party/mojo/src/mojo/edk/embedder/embedder.h" #include "ui/base/resource/resource_bundle.h" +#include "ui/gfx/display.h" #include "ui/gfx/geometry/size.h" #include "ui/mojo/init/ui_init.h" @@ -20,11 +23,17 @@ namespace { +std::vector<gfx::Display> GetTestDisplays() { + std::vector<gfx::Display> displays(1); + displays[0].set_id(2000); + displays[0].SetScaleAndBounds(1., gfx::Rect(0, 0, 800, 600)); + return displays; +} + class NoAtExitBaseTestSuite : public base::TestSuite { public: NoAtExitBaseTestSuite(int argc, char** argv) - : base::TestSuite(argc, argv, false), - ui_init_(gfx::Size(800, 600), 1.f) { + : base::TestSuite(argc, argv, false), ui_init_(GetTestDisplays()) { #if defined(OS_ANDROID) base::MemoryMappedFile::Region resource_file_region; int fd = base::android::OpenApkAsset("assets/html_viewer.pak",
diff --git a/components/html_viewer/web_layer_tree_view_impl.cc b/components/html_viewer/web_layer_tree_view_impl.cc index 9b1f468..c54081e1 100644 --- a/components/html_viewer/web_layer_tree_view_impl.cc +++ b/components/html_viewer/web_layer_tree_view_impl.cc
@@ -12,7 +12,7 @@ #include "cc/trees/layer_tree_host.h" #include "components/mus/public/cpp/context_provider.h" #include "components/mus/public/cpp/output_surface.h" -#include "components/mus/public/cpp/view.h" +#include "components/mus/public/cpp/window.h" #include "mojo/converters/surfaces/surfaces_type_converters.h" #include "third_party/WebKit/public/web/WebWidget.h" #include "ui/gfx/buffer_types.h" @@ -23,8 +23,8 @@ scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, cc::TaskGraphRunner* task_graph_runner) - : widget_(NULL), - view_(NULL), + : widget_(nullptr), + window_(nullptr), main_thread_compositor_task_runner_(base::ThreadTaskRunnerHandle::Get()), weak_factory_(this) { main_thread_bound_weak_ptr_ = weak_factory_.GetWeakPtr(); @@ -58,9 +58,9 @@ } void WebLayerTreeViewImpl::Initialize(mojo::GpuPtr gpu_service, - mus::View* view, + mus::Window* window, blink::WebWidget* widget) { - view_ = view; + window_ = window; widget_ = widget; if (gpu_service) { mojo::CommandBufferPtr cb; @@ -68,9 +68,9 @@ scoped_refptr<cc::ContextProvider> context_provider( new mus::ContextProvider(cb.PassInterface().PassHandle())); output_surface_.reset( - new mus::OutputSurface(context_provider, view_->RequestSurface())); + new mus::OutputSurface(context_provider, window_->RequestSurface())); } - layer_tree_host_->SetVisible(view_->visible()); + layer_tree_host_->SetVisible(window_->visible()); } WebLayerTreeViewImpl::~WebLayerTreeViewImpl() { @@ -196,8 +196,9 @@ // viewports. overscrollElasticityLayer ? static_cast<const cc_blink::WebLayerImpl*>( - overscrollElasticityLayer)->layer() - : NULL, + overscrollElasticityLayer) + ->layer() + : nullptr, static_cast<const cc_blink::WebLayerImpl*>(pageScaleLayer)->layer(), static_cast<const cc_blink::WebLayerImpl*>(innerViewportScrollLayer) ->layer(), @@ -206,7 +207,7 @@ outerViewportScrollLayer ? static_cast<const cc_blink::WebLayerImpl*>(outerViewportScrollLayer) ->layer() - : NULL); + : nullptr); } void WebLayerTreeViewImpl::clearViewportLayers() {
diff --git a/components/html_viewer/web_layer_tree_view_impl.h b/components/html_viewer/web_layer_tree_view_impl.h index ed16fab..8ca4302f 100644 --- a/components/html_viewer/web_layer_tree_view_impl.h +++ b/components/html_viewer/web_layer_tree_view_impl.h
@@ -32,10 +32,6 @@ class GpuMemoryBufferManager; } -namespace mojo { -class View; -} - namespace html_viewer { class WebLayerTreeViewImpl : public blink::WebLayerTreeView, @@ -48,7 +44,7 @@ ~WebLayerTreeViewImpl() override; void Initialize(mojo::GpuPtr gpu_service, - mus::View* view, + mus::Window* window, blink::WebWidget* widget); // cc::LayerTreeHostClient implementation. @@ -112,9 +108,9 @@ virtual void setShowScrollBottleneckRects(bool) {} private: - // widget_ and view_ will outlive us. + // widget_ and window_ will outlive us. blink::WebWidget* widget_; - mus::View* view_; + mus::Window* window_; scoped_ptr<cc::LayerTreeHost> layer_tree_host_; scoped_ptr<cc::OutputSurface> output_surface_; scoped_refptr<base::SingleThreadTaskRunner>
diff --git a/components/mus/example/common/BUILD.gn b/components/mus/example/common/BUILD.gn index 5cb41f0..e2f9f9b9 100644 --- a/components/mus/example/common/BUILD.gn +++ b/components/mus/example/common/BUILD.gn
@@ -21,6 +21,8 @@ "//components/mus/public/interfaces", "//mojo/application/public/cpp", "//mojo/application/public/cpp:sources", + "//mojo/converters/geometry", + "//mojo/converters/network", "//third_party/mojo/src/mojo/public/cpp/bindings", "//ui/views", "//ui/views/mus",
diff --git a/components/mus/example/common/mus_views_init.cc b/components/mus/example/common/mus_views_init.cc index bb4087f2..6c9863d 100644 --- a/components/mus/example/common/mus_views_init.cc +++ b/components/mus/example/common/mus_views_init.cc
@@ -4,19 +4,83 @@ #include "components/mus/example/common/mus_views_init.h" -#include "components/mus/public/cpp/view_tree_connection.h" +#include "components/mus/public/cpp/window_tree_connection.h" #include "components/mus/public/interfaces/view_tree.mojom.h" #include "components/mus/public/interfaces/window_manager.mojom.h" #include "mojo/application/public/cpp/application_connection.h" #include "mojo/application/public/cpp/application_impl.h" -#include "ui/views/mus/aura_init.h" +#include "mojo/converters/geometry/geometry_type_converters.h" +#include "mojo/converters/network/network_type_converters.h" +#include "ui/gfx/display.h" +#include "ui/gfx/geometry/point_conversions.h" +#include "ui/gfx/geometry/rect.h" #include "ui/views/mus/native_widget_view_manager.h" -MUSViewsInit::MUSViewsInit(mojo::ApplicationImpl* app) : app_(app) {} +namespace mojo { + +gfx::Display::Rotation GFXRotationFromMojomRotation( + mus::mojom::Rotation input) { + switch (input) { + case mus::mojom::ROTATION_VALUE_0: + return gfx::Display::ROTATE_0; + case mus::mojom::ROTATION_VALUE_90: + return gfx::Display::ROTATE_90; + case mus::mojom::ROTATION_VALUE_180: + return gfx::Display::ROTATE_180; + case mus::mojom::ROTATION_VALUE_270: + return gfx::Display::ROTATE_270; + } + return gfx::Display::ROTATE_0; +} + +template <> +struct TypeConverter<gfx::Display, mus::mojom::DisplayPtr> { + static gfx::Display Convert(const mus::mojom::DisplayPtr& input) { + gfx::Display result; + result.set_id(input->id); + result.SetScaleAndBounds(input->device_pixel_ratio, + input->bounds.To<gfx::Rect>()); + gfx::Rect work_area( + gfx::ToFlooredPoint(gfx::ScalePoint( + gfx::Point(input->work_area->x, input->work_area->y), + 1.0f / input->device_pixel_ratio)), + gfx::ScaleToFlooredSize( + gfx::Size(input->work_area->width, input->work_area->height), + 1.0f / input->device_pixel_ratio)); + result.set_work_area(work_area); + result.set_rotation(GFXRotationFromMojomRotation(input->rotation)); + return result; + } +}; + +} // namespace mojo + +namespace { + +std::vector<gfx::Display> GetDisplaysFromWindowManager( + mojo::ApplicationImpl* app) { + mus::mojom::WindowManagerPtr window_manager; + app->ConnectToService(mojo::URLRequest::From(std::string("mojo:example_wm")), + &window_manager); + std::vector<gfx::Display> displays; + window_manager->GetDisplays( + [&displays](mojo::Array<mus::mojom::DisplayPtr> mojom_displays) { + displays = mojom_displays.To<std::vector<gfx::Display>>(); + }); + CHECK(window_manager.WaitForIncomingResponse()); + return displays; +} +} + +MUSViewsInit::MUSViewsInit(mojo::ApplicationImpl* app) + : app_(app), + aura_init_(app, + "example_resources.pak", + GetDisplaysFromWindowManager(app)) {} MUSViewsInit::~MUSViewsInit() {} -mus::View* MUSViewsInit::CreateWindow() { +mus::Window* MUSViewsInit::CreateWindow() { mus::mojom::WindowManagerPtr wm; mojo::URLRequestPtr request(mojo::URLRequest::New()); request->url = "mojo:example_wm"; @@ -25,10 +89,10 @@ mojo::InterfaceRequest<mojo::ViewTreeClient> view_tree_client_request = GetProxy(&view_tree_client); wm->OpenWindow(view_tree_client.Pass()); - mus::ViewTreeConnection* view_tree_connection = - mus::ViewTreeConnection::Create( + mus::WindowTreeConnection* view_tree_connection = + mus::WindowTreeConnection::Create( this, view_tree_client_request.Pass(), - mus::ViewTreeConnection::CreateType::WAIT_FOR_EMBED); + mus::WindowTreeConnection::CreateType::WAIT_FOR_EMBED); DCHECK(view_tree_connection->GetRoot()); return view_tree_connection->GetRoot(); } @@ -43,14 +107,10 @@ views::Widget::InitParams* params, views::internal::NativeWidgetDelegate* delegate) {} -void MUSViewsInit::OnEmbed(mus::View* root) { - if (!aura_init_) { - aura_init_.reset( - new views::AuraInit(root, app_->shell(), "example_resources.pak")); - } +void MUSViewsInit::OnEmbed(mus::Window* root) { } -void MUSViewsInit::OnConnectionLost(mus::ViewTreeConnection* connection) {} +void MUSViewsInit::OnConnectionLost(mus::WindowTreeConnection* connection) {} #if defined(OS_WIN) HICON MUSViewsInit::GetSmallWindowIcon() const {
diff --git a/components/mus/example/common/mus_views_init.h b/components/mus/example/common/mus_views_init.h index 355b25a..a12bddc 100644 --- a/components/mus/example/common/mus_views_init.h +++ b/components/mus/example/common/mus_views_init.h
@@ -6,7 +6,8 @@ #define COMPONENTS_MUS_EXAMPLE_COMMON_MUS_VIEWS_INIT_H_ #include "base/memory/scoped_ptr.h" -#include "components/mus/public/cpp/view_tree_delegate.h" +#include "components/mus/public/cpp/window_tree_delegate.h" +#include "ui/views/mus/aura_init.h" #include "ui/views/views_delegate.h" namespace mojo { @@ -18,13 +19,14 @@ } // Does the necessary setup to use mus, views and the example wm. -class MUSViewsInit : public views::ViewsDelegate, public mus::ViewTreeDelegate { +class MUSViewsInit : public views::ViewsDelegate, + public mus::WindowTreeDelegate { public: explicit MUSViewsInit(mojo::ApplicationImpl* app); ~MUSViewsInit() override; private: - mus::View* CreateWindow(); + mus::Window* CreateWindow(); // views::ViewsDelegate: views::NativeWidget* CreateNativeWidget( @@ -33,16 +35,16 @@ views::Widget::InitParams* params, views::internal::NativeWidgetDelegate* delegate) override; - // mus::ViewTreeDelegate: - void OnEmbed(mus::View* root) override; - void OnConnectionLost(mus::ViewTreeConnection* connection) override; + // mus::WindowTreeDelegate: + void OnEmbed(mus::Window* root) override; + void OnConnectionLost(mus::WindowTreeConnection* connection) override; #if defined(OS_WIN) HICON GetSmallWindowIcon() const override; #endif mojo::ApplicationImpl* app_; - scoped_ptr<views::AuraInit> aura_init_; + views::AuraInit aura_init_; DISALLOW_COPY_AND_ASSIGN(MUSViewsInit); };
diff --git a/components/mus/example/views_examples/views_examples_application_delegate.cc b/components/mus/example/views_examples/views_examples_application_delegate.cc index 889186cf..d02cb67 100644 --- a/components/mus/example/views_examples/views_examples_application_delegate.cc +++ b/components/mus/example/views_examples/views_examples_application_delegate.cc
@@ -9,7 +9,6 @@ #include "mojo/application/public/cpp/application_impl.h" #include "ui/views/examples/example_base.h" #include "ui/views/examples/examples_window.h" -#include "ui/views/widget/widget_delegate.h" ViewsExamplesApplicationDelegate::ViewsExamplesApplicationDelegate() : app_(nullptr) {} @@ -22,12 +21,6 @@ mus_views_init_.reset(new MUSViewsInit(app)); - // TODO(sky): total hack! This is necessary as WindowTypeLauncherView is - // created before AuraInit. WindowTypeLauncherView uses resources that are - // configured by MUSViewsInit once a View is created. By creating a Widget - // here we ensure the necessary state has been setup. - views::Widget::CreateWindow(new views::WidgetDelegateView); - views::examples::ShowExamplesWindow(views::examples::DO_NOTHING_ON_CLOSE, nullptr, nullptr); }
diff --git a/components/mus/example/window_type_launcher/window_type_launcher.cc b/components/mus/example/window_type_launcher/window_type_launcher.cc index e7f0d745..07eb8787 100644 --- a/components/mus/example/window_type_launcher/window_type_launcher.cc +++ b/components/mus/example/window_type_launcher/window_type_launcher.cc
@@ -358,12 +358,6 @@ mus_views_init_.reset(new MUSViewsInit(app)); - // TODO(sky): total hack! This is necessary as WindowTypeLauncherView is - // created before AuraInit. WindowTypeLauncherView uses resources that are - // configured by MUSViewsInit once a View is created. By creating a Widget - // here we ensure the necessary state has been setup. - views::Widget::CreateWindow(new views::WidgetDelegateView); - views::Widget* widget = new views::Widget; views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); params.delegate = new WindowTypeLauncherView;
diff --git a/components/mus/example/wm/window_manager_application.cc b/components/mus/example/wm/window_manager_application.cc index 289c318..79c2e0f 100644 --- a/components/mus/example/wm/window_manager_application.cc +++ b/components/mus/example/wm/window_manager_application.cc
@@ -7,9 +7,9 @@ #include "components/mus/example/wm/container.h" #include "components/mus/example/wm/window_manager_impl.h" #include "components/mus/public/cpp/util.h" -#include "components/mus/public/cpp/view.h" -#include "components/mus/public/cpp/view_tree_connection.h" -#include "components/mus/public/cpp/view_tree_host_factory.h" +#include "components/mus/public/cpp/window.h" +#include "components/mus/public/cpp/window_tree_connection.h" +#include "components/mus/public/cpp/window_tree_host_factory.h" #include "mojo/application/public/cpp/application_connection.h" WindowManagerApplication::WindowManagerApplication() @@ -17,7 +17,7 @@ WindowManagerApplication::~WindowManagerApplication() {} void WindowManagerApplication::Initialize(mojo::ApplicationImpl* app) { - mus::CreateSingleViewTreeHost(app, this, &host_); + mus::CreateSingleWindowTreeHost(app, this, &host_); } bool WindowManagerApplication::ConfigureIncomingConnection( @@ -26,7 +26,7 @@ return true; } -void WindowManagerApplication::OnEmbed(mus::View* root) { +void WindowManagerApplication::OnEmbed(mus::Window* root) { root_ = root; CreateContainers(); @@ -35,7 +35,7 @@ } void WindowManagerApplication::OnConnectionLost( - mus::ViewTreeConnection* connection) { + mus::WindowTreeConnection* connection) { // TODO(sky): shutdown. NOTIMPLEMENTED(); } @@ -54,12 +54,12 @@ void WindowManagerApplication::CreateContainers() { for (uint16 container = static_cast<uint16>(Container::ALL_USER_BACKGROUND); container < static_cast<uint16>(Container::COUNT); ++container) { - mus::View* view = root_->connection()->CreateView(); - DCHECK_EQ(mus::LoWord(view->id()), container) - << "Containers must be created before other views!"; - view->SetBounds(root_->bounds()); - view->SetVisible(true); - root_->AddChild(view); + mus::Window* window = root_->connection()->CreateWindow(); + DCHECK_EQ(mus::LoWord(window->id()), container) + << "Containers must be created before other windows!"; + window->SetBounds(root_->bounds()); + window->SetVisible(true); + root_->AddChild(window); } }
diff --git a/components/mus/example/wm/window_manager_application.h b/components/mus/example/wm/window_manager_application.h index 7e73772..79d45e6 100644 --- a/components/mus/example/wm/window_manager_application.h +++ b/components/mus/example/wm/window_manager_application.h
@@ -8,7 +8,7 @@ #include "base/macros.h" #include "base/memory/scoped_ptr.h" #include "base/memory/scoped_vector.h" -#include "components/mus/public/cpp/view_tree_delegate.h" +#include "components/mus/public/cpp/window_tree_delegate.h" #include "components/mus/public/interfaces/view_tree_host.mojom.h" #include "components/mus/public/interfaces/window_manager.mojom.h" #include "mojo/application/public/cpp/application_delegate.h" @@ -16,13 +16,13 @@ class WindowManagerApplication : public mojo::ApplicationDelegate, - public mus::ViewTreeDelegate, + public mus::WindowTreeDelegate, public mojo::InterfaceFactory<mus::mojom::WindowManager> { public: WindowManagerApplication(); ~WindowManagerApplication() override; - mus::View* root() { return root_; } + mus::Window* root() { return root_; } int window_count() { return window_count_; } void IncrementWindowCount() { ++window_count_; } @@ -34,8 +34,8 @@ mojo::ApplicationConnection* connection) override; // ViewTreeDelegate: - void OnEmbed(mus::View* root) override; - void OnConnectionLost(mus::ViewTreeConnection* connection) override; + void OnEmbed(mus::Window* root) override; + void OnConnectionLost(mus::WindowTreeConnection* connection) override; // InterfaceFactory<mus::mojom::WindowManager>: void Create( @@ -46,7 +46,7 @@ void CreateContainers(); // nullptr until the Mus connection is established via OnEmbed(). - mus::View* root_; + mus::Window* root_; int window_count_; mojo::ViewTreeHostPtr host_;
diff --git a/components/mus/example/wm/window_manager_impl.cc b/components/mus/example/wm/window_manager_impl.cc index 41b29e08..256fa14 100644 --- a/components/mus/example/wm/window_manager_impl.cc +++ b/components/mus/example/wm/window_manager_impl.cc
@@ -7,13 +7,13 @@ #include "components/mus/example/wm/container.h" #include "components/mus/example/wm/window_manager_application.h" #include "components/mus/public/cpp/types.h" -#include "components/mus/public/cpp/view.h" -#include "components/mus/public/cpp/view_tree_connection.h" +#include "components/mus/public/cpp/window.h" +#include "components/mus/public/cpp/window_tree_connection.h" namespace { -mus::Id GetViewIdForContainer(mus::ViewTreeConnection* connection, - Container container) { +mus::Id GetWindowIdForContainer(mus::WindowTreeConnection* connection, + Container container) { return connection->GetConnectionId() << 16 | static_cast<uint16>(container); } @@ -29,29 +29,42 @@ WindowManagerImpl::~WindowManagerImpl() {} void WindowManagerImpl::OpenWindow(mojo::ViewTreeClientPtr client) { - mus::View* root = state_->root(); + mus::Window* root = state_->root(); DCHECK(root); - mus::Id container_view_id = GetViewIdForContainer(root->connection(), - Container::USER_WINDOWS); - mus::View* container_view = root->GetChildById(container_view_id); + mus::Id container_window_id = + GetWindowIdForContainer(root->connection(), Container::USER_WINDOWS); + mus::Window* container_window = root->GetChildById(container_window_id); const int width = (root->bounds().width - 240); const int height = (root->bounds().height - 240); - mus::View* child_view = root->connection()->CreateView(); + mus::Window* child_window = root->connection()->CreateWindow(); mojo::Rect bounds; bounds.x = 40 + (state_->window_count() % 4) * 40; bounds.y = 40 + (state_->window_count() % 4) * 40; bounds.width = width; bounds.height = height; - child_view->SetBounds(bounds); - container_view->AddChild(child_view); - child_view->Embed(client.Pass()); + child_window->SetBounds(bounds); + container_window->AddChild(child_window); + child_window->Embed(client.Pass()); state_->IncrementWindowCount(); } -void WindowManagerImpl::CenterWindow(uint32_t view_id, mojo::SizePtr size) { +void WindowManagerImpl::CenterWindow(uint32_t window_id, mojo::SizePtr size) { // TODO(beng): } +void WindowManagerImpl::GetDisplays(const GetDisplaysCallback& callback) { + mojo::Array<mus::mojom::DisplayPtr> displays(1); + displays[0] = mus::mojom::Display::New(); + displays[0]->id = 2001; + displays[0]->bounds = mojo::Rect::New(); + displays[0]->bounds->y = 0; + displays[0]->bounds->width = state_->root()->bounds().width; + displays[0]->bounds->height = state_->root()->bounds().width; + displays[0]->work_area = displays[0]->bounds.Clone(); + displays[0]->device_pixel_ratio = + state_->root()->viewport_metrics().device_pixel_ratio; + callback.Run(displays.Pass()); +}
diff --git a/components/mus/example/wm/window_manager_impl.h b/components/mus/example/wm/window_manager_impl.h index cdac569..d0a23482 100644 --- a/components/mus/example/wm/window_manager_impl.h +++ b/components/mus/example/wm/window_manager_impl.h
@@ -20,7 +20,8 @@ private: // mus::mojom::WindowManager: void OpenWindow(mojo::ViewTreeClientPtr client) override; - void CenterWindow(uint32_t view_id, mojo::SizePtr size) override; + void CenterWindow(uint32_t window_id, mojo::SizePtr size) override; + void GetDisplays(const GetDisplaysCallback& callback) override; WindowManagerApplication* state_; mojo::StrongBinding<mus::mojom::WindowManager> binding_;
diff --git a/components/mus/mus_app.cc b/components/mus/mus_app.cc index 120fc79f..3cb357a 100644 --- a/components/mus/mus_app.cc +++ b/components/mus/mus_app.cc
@@ -71,9 +71,7 @@ bool MandolineUIServicesApp::ConfigureIncomingConnection( ApplicationConnection* connection) { - // MandolineUIServices connection->AddService<ViewTreeHostFactory>(this); - // GPU connection->AddService<Gpu>(this); return true; } @@ -124,7 +122,7 @@ new GpuImpl(request.Pass(), gpu_state_); } -void MandolineUIServicesApp::CreateViewTreeHost( +void MandolineUIServicesApp::CreateWindowTreeHost( mojo::InterfaceRequest<mojo::ViewTreeHost> host, mojo::ViewTreeHostClientPtr host_client, mojo::ViewTreeClientPtr tree_client) {
diff --git a/components/mus/mus_app.h b/components/mus/mus_app.h index 9a7e8f5..c46ab0cb 100644 --- a/components/mus/mus_app.h +++ b/components/mus/mus_app.h
@@ -75,9 +75,9 @@ mojo::InterfaceRequest<mojo::Gpu> request) override; // mojo::ViewTreeHostFactory implementation. - void CreateViewTreeHost(mojo::InterfaceRequest<mojo::ViewTreeHost> host, - mojo::ViewTreeHostClientPtr host_client, - mojo::ViewTreeClientPtr tree_client) override; + void CreateWindowTreeHost(mojo::InterfaceRequest<mojo::ViewTreeHost> host, + mojo::ViewTreeHostClientPtr host_client, + mojo::ViewTreeClientPtr tree_client) override; mojo::WeakBindingSet<mojo::ViewTreeHostFactory> factory_bindings_; mojo::ApplicationImpl* app_impl_;
diff --git a/components/mus/public/cpp/BUILD.gn b/components/mus/public/cpp/BUILD.gn index 51304e3..27bdbce 100644 --- a/components/mus/public/cpp/BUILD.gn +++ b/components/mus/public/cpp/BUILD.gn
@@ -10,28 +10,28 @@ "context_provider.h", "lib/context_provider.cc", "lib/output_surface.cc", - "lib/scoped_view_ptr.cc", - "lib/view.cc", - "lib/view_observer.cc", - "lib/view_private.cc", - "lib/view_private.h", - "lib/view_surface.cc", - "lib/view_tree_client_impl.cc", - "lib/view_tree_client_impl.h", - "lib/view_tree_delegate.cc", - "lib/view_tree_host_factory.cc", + "lib/scoped_window_ptr.cc", + "lib/window.cc", + "lib/window_observer.cc", + "lib/window_private.cc", + "lib/window_private.h", + "lib/window_surface.cc", + "lib/window_tree_client_impl.cc", + "lib/window_tree_client_impl.h", + "lib/window_tree_delegate.cc", + "lib/window_tree_host_factory.cc", "output_surface.h", - "scoped_view_ptr.h", - "view.h", - "view_observer.h", - "view_property.h", - "view_surface.h", - "view_surface_client.h", - "view_tracker.cc", - "view_tracker.h", - "view_tree_connection.h", - "view_tree_delegate.h", - "view_tree_host_factory.h", + "scoped_window_ptr.h", + "window.h", + "window_observer.h", + "window_property.h", + "window_surface.h", + "window_surface_client.h", + "window_tracker.cc", + "window_tracker.h", + "window_tree_connection.h", + "window_tree_delegate.h", + "window_tree_host_factory.h", ] public_deps = [
diff --git a/components/mus/public/cpp/lib/output_surface.cc b/components/mus/public/cpp/lib/output_surface.cc index 77b2422..5b195f7 100644 --- a/components/mus/public/cpp/lib/output_surface.cc +++ b/components/mus/public/cpp/lib/output_surface.cc
@@ -8,14 +8,14 @@ #include "cc/output/compositor_frame.h" #include "cc/output/compositor_frame_ack.h" #include "cc/output/output_surface_client.h" -#include "components/mus/public/cpp/view_surface.h" +#include "components/mus/public/cpp/window_surface.h" #include "mojo/converters/surfaces/surfaces_type_converters.h" namespace mus { OutputSurface::OutputSurface( const scoped_refptr<cc::ContextProvider>& context_provider, - scoped_ptr<mus::ViewSurface> surface) + scoped_ptr<mus::WindowSurface> surface) : cc::OutputSurface(context_provider), surface_(surface.Pass()) { capabilities_.delegated_rendering = true; capabilities_.max_frames_pending = 1; @@ -37,7 +37,7 @@ void OutputSurface::SwapBuffers(cc::CompositorFrame* frame) { // TODO(fsamuel, rjkroege): We should probably throttle compositor frames. client_->DidSwapBuffers(); - // OutputSurface owns ViewSurface, and so if OutputSurface is + // OutputSurface owns WindowSurface, and so if OutputSurface is // destroyed then SubmitCompositorFrame's callback will never get called. // Thus, base::Unretained is safe here. surface_->SubmitCompositorFrame( @@ -46,7 +46,7 @@ } void OutputSurface::OnResourcesReturned( - mus::ViewSurface* surface, + mus::WindowSurface* surface, mojo::Array<mojo::ReturnedResourcePtr> resources) { cc::CompositorFrameAck cfa; cfa.resources = resources.To<cc::ReturnedResourceArray>();
diff --git a/components/mus/public/cpp/lib/scoped_view_ptr.cc b/components/mus/public/cpp/lib/scoped_view_ptr.cc deleted file mode 100644 index 4c41709..0000000 --- a/components/mus/public/cpp/lib/scoped_view_ptr.cc +++ /dev/null
@@ -1,44 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/mus/public/cpp/scoped_view_ptr.h" - -#include "components/mus/public/cpp/view.h" -#include "components/mus/public/cpp/view_observer.h" -#include "components/mus/public/cpp/view_tree_connection.h" - -namespace mus { - -ScopedViewPtr::ScopedViewPtr(View* view) : view_(view) { - view_->AddObserver(this); -} - -ScopedViewPtr::~ScopedViewPtr() { - if (view_) - DeleteViewOrViewManager(view_); - DetachFromView(); -} - -// static -void ScopedViewPtr::DeleteViewOrViewManager(View* view) { - if (view->connection()->GetRoot() == view) - delete view->connection(); - else - view->Destroy(); -} - -void ScopedViewPtr::DetachFromView() { - if (!view_) - return; - - view_->RemoveObserver(this); - view_ = nullptr; -} - -void ScopedViewPtr::OnViewDestroying(View* view) { - DCHECK_EQ(view_, view); - DetachFromView(); -} - -} // namespace mus
diff --git a/components/mus/public/cpp/lib/scoped_window_ptr.cc b/components/mus/public/cpp/lib/scoped_window_ptr.cc new file mode 100644 index 0000000..cf734cb --- /dev/null +++ b/components/mus/public/cpp/lib/scoped_window_ptr.cc
@@ -0,0 +1,44 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/mus/public/cpp/scoped_window_ptr.h" + +#include "components/mus/public/cpp/window.h" +#include "components/mus/public/cpp/window_observer.h" +#include "components/mus/public/cpp/window_tree_connection.h" + +namespace mus { + +ScopedWindowPtr::ScopedWindowPtr(Window* window) : window_(window) { + window_->AddObserver(this); +} + +ScopedWindowPtr::~ScopedWindowPtr() { + if (window_) + DeleteWindowOrWindowManager(window_); + DetachFromWindow(); +} + +// static +void ScopedWindowPtr::DeleteWindowOrWindowManager(Window* window) { + if (window->connection()->GetRoot() == window) + delete window->connection(); + else + window->Destroy(); +} + +void ScopedWindowPtr::DetachFromWindow() { + if (!window_) + return; + + window_->RemoveObserver(this); + window_ = nullptr; +} + +void ScopedWindowPtr::OnWindowDestroying(Window* window) { + DCHECK_EQ(window_, window); + DetachFromWindow(); +} + +} // namespace mus
diff --git a/components/mus/public/cpp/lib/view.cc b/components/mus/public/cpp/lib/view.cc deleted file mode 100644 index 88228eb..0000000 --- a/components/mus/public/cpp/lib/view.cc +++ /dev/null
@@ -1,615 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/mus/public/cpp/view.h" - -#include <set> -#include <string> - -#include "base/bind.h" -#include "components/mus/public/cpp/lib/view_private.h" -#include "components/mus/public/cpp/lib/view_tree_client_impl.h" -#include "components/mus/public/cpp/view_observer.h" -#include "components/mus/public/cpp/view_surface.h" -#include "components/mus/public/cpp/view_tracker.h" -#include "mojo/application/public/cpp/service_provider_impl.h" - -namespace mus { - -namespace { - -void NotifyViewTreeChangeAtReceiver( - View* receiver, - const ViewObserver::TreeChangeParams& params, - bool change_applied) { - ViewObserver::TreeChangeParams local_params = params; - local_params.receiver = receiver; - if (change_applied) { - FOR_EACH_OBSERVER(ViewObserver, *ViewPrivate(receiver).observers(), - OnTreeChanged(local_params)); - } else { - FOR_EACH_OBSERVER(ViewObserver, *ViewPrivate(receiver).observers(), - OnTreeChanging(local_params)); - } -} - -void NotifyViewTreeChangeUp(View* start_at, - const ViewObserver::TreeChangeParams& params, - bool change_applied) { - for (View* current = start_at; current; current = current->parent()) - NotifyViewTreeChangeAtReceiver(current, params, change_applied); -} - -void NotifyViewTreeChangeDown(View* start_at, - const ViewObserver::TreeChangeParams& params, - bool change_applied) { - NotifyViewTreeChangeAtReceiver(start_at, params, change_applied); - View::Children::const_iterator it = start_at->children().begin(); - for (; it != start_at->children().end(); ++it) - NotifyViewTreeChangeDown(*it, params, change_applied); -} - -void NotifyViewTreeChange(const ViewObserver::TreeChangeParams& params, - bool change_applied) { - NotifyViewTreeChangeDown(params.target, params, change_applied); - if (params.old_parent) - NotifyViewTreeChangeUp(params.old_parent, params, change_applied); - if (params.new_parent) - NotifyViewTreeChangeUp(params.new_parent, params, change_applied); -} - -class ScopedTreeNotifier { - public: - ScopedTreeNotifier(View* target, View* old_parent, View* new_parent) { - params_.target = target; - params_.old_parent = old_parent; - params_.new_parent = new_parent; - NotifyViewTreeChange(params_, false); - } - ~ScopedTreeNotifier() { NotifyViewTreeChange(params_, true); } - - private: - ViewObserver::TreeChangeParams params_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(ScopedTreeNotifier); -}; - -void RemoveChildImpl(View* child, View::Children* children) { - View::Children::iterator it = - std::find(children->begin(), children->end(), child); - if (it != children->end()) { - children->erase(it); - ViewPrivate(child).ClearParent(); - } -} - -class ScopedOrderChangedNotifier { - public: - ScopedOrderChangedNotifier(View* view, - View* relative_view, - mojo::OrderDirection direction) - : view_(view), relative_view_(relative_view), direction_(direction) { - FOR_EACH_OBSERVER(ViewObserver, *ViewPrivate(view_).observers(), - OnViewReordering(view_, relative_view_, direction_)); - } - ~ScopedOrderChangedNotifier() { - FOR_EACH_OBSERVER(ViewObserver, *ViewPrivate(view_).observers(), - OnViewReordered(view_, relative_view_, direction_)); - } - - private: - View* view_; - View* relative_view_; - mojo::OrderDirection direction_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(ScopedOrderChangedNotifier); -}; - -// Returns true if the order actually changed. -bool ReorderImpl(View::Children* children, - View* view, - View* relative, - mojo::OrderDirection direction) { - DCHECK(relative); - DCHECK_NE(view, relative); - DCHECK_EQ(view->parent(), relative->parent()); - - const size_t child_i = - std::find(children->begin(), children->end(), view) - children->begin(); - const size_t target_i = - std::find(children->begin(), children->end(), relative) - - children->begin(); - if ((direction == mojo::ORDER_DIRECTION_ABOVE && child_i == target_i + 1) || - (direction == mojo::ORDER_DIRECTION_BELOW && child_i + 1 == target_i)) { - return false; - } - - ScopedOrderChangedNotifier notifier(view, relative, direction); - - const size_t dest_i = direction == mojo::ORDER_DIRECTION_ABOVE - ? (child_i < target_i ? target_i : target_i + 1) - : (child_i < target_i ? target_i - 1 : target_i); - children->erase(children->begin() + child_i); - children->insert(children->begin() + dest_i, view); - - return true; -} - -class ScopedSetBoundsNotifier { - public: - ScopedSetBoundsNotifier(View* view, - const mojo::Rect& old_bounds, - const mojo::Rect& new_bounds) - : view_(view), old_bounds_(old_bounds), new_bounds_(new_bounds) { - FOR_EACH_OBSERVER(ViewObserver, *ViewPrivate(view_).observers(), - OnViewBoundsChanging(view_, old_bounds_, new_bounds_)); - } - ~ScopedSetBoundsNotifier() { - FOR_EACH_OBSERVER(ViewObserver, *ViewPrivate(view_).observers(), - OnViewBoundsChanged(view_, old_bounds_, new_bounds_)); - } - - private: - View* view_; - const mojo::Rect old_bounds_; - const mojo::Rect new_bounds_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(ScopedSetBoundsNotifier); -}; - -// Some operations are only permitted in the connection that created the view. -bool OwnsView(ViewTreeConnection* connection, View* view) { - return !connection || - static_cast<ViewTreeClientImpl*>(connection)->OwnsView(view->id()); -} - -void EmptyEmbedCallback(bool result, ConnectionSpecificId connection_id) {} - -} // namespace - -//////////////////////////////////////////////////////////////////////////////// -// View, public: - -void View::Destroy() { - if (!OwnsView(connection_, this)) - return; - - if (connection_) - static_cast<ViewTreeClientImpl*>(connection_)->DestroyView(id_); - while (!children_.empty()) { - View* child = children_.front(); - if (!OwnsView(connection_, child)) { - ViewPrivate(child).ClearParent(); - children_.erase(children_.begin()); - } else { - child->Destroy(); - DCHECK(std::find(children_.begin(), children_.end(), child) == - children_.end()); - } - } - LocalDestroy(); -} - -void View::SetBounds(const mojo::Rect& bounds) { - if (!OwnsView(connection_, this)) - return; - - if (bounds_.Equals(bounds)) - return; - - if (connection_) - static_cast<ViewTreeClientImpl*>(connection_)->SetBounds(id_, bounds); - LocalSetBounds(bounds_, bounds); -} - -void View::SetVisible(bool value) { - if (visible_ == value) - return; - - if (connection_) - static_cast<ViewTreeClientImpl*>(connection_)->SetVisible(id_, value); - LocalSetVisible(value); -} - -scoped_ptr<ViewSurface> View::RequestSurface() { - mojo::SurfacePtr surface; - mojo::SurfaceClientPtr client; - mojo::InterfaceRequest<mojo::SurfaceClient> client_request = - GetProxy(&client); - static_cast<ViewTreeClientImpl*>(connection_) - ->RequestSurface(id_, GetProxy(&surface), client.Pass()); - return make_scoped_ptr( - new ViewSurface(surface.PassInterface(), client_request.Pass())); -} - -void View::SetSharedProperty(const std::string& name, - const std::vector<uint8_t>* value) { - std::vector<uint8_t> old_value; - std::vector<uint8_t>* old_value_ptr = nullptr; - auto it = properties_.find(name); - if (it != properties_.end()) { - old_value = it->second; - old_value_ptr = &old_value; - - if (value && old_value == *value) - return; - } else if (!value) { - // This property isn't set in |properties_| and |value| is NULL, so there's - // no change. - return; - } - - if (value) { - properties_[name] = *value; - } else if (it != properties_.end()) { - properties_.erase(it); - } - - // TODO: add test coverage of this (450303). - if (connection_) { - mojo::Array<uint8_t> transport_value; - if (value) { - transport_value.resize(value->size()); - if (value->size()) - memcpy(&transport_value.front(), &(value->front()), value->size()); - } - static_cast<ViewTreeClientImpl*>(connection_) - ->SetProperty(id_, name, transport_value.Pass()); - } - - FOR_EACH_OBSERVER( - ViewObserver, observers_, - OnViewSharedPropertyChanged(this, name, old_value_ptr, value)); -} - -bool View::IsDrawn() const { - if (!visible_) - return false; - return parent_ ? parent_->IsDrawn() : drawn_; -} - -void View::AddObserver(ViewObserver* observer) { - observers_.AddObserver(observer); -} - -void View::RemoveObserver(ViewObserver* observer) { - observers_.RemoveObserver(observer); -} - -const View* View::GetRoot() const { - const View* root = this; - for (const View* parent = this; parent; parent = parent->parent()) - root = parent; - return root; -} - -void View::AddChild(View* child) { - // TODO(beng): not necessarily valid to all connections, but possibly to the - // embeddee in an embedder-embeddee relationship. - if (connection_) - CHECK_EQ(child->connection(), connection_); - LocalAddChild(child); - if (connection_) - static_cast<ViewTreeClientImpl*>(connection_)->AddChild(child->id(), id_); -} - -void View::RemoveChild(View* child) { - // TODO(beng): not necessarily valid to all connections, but possibly to the - // embeddee in an embedder-embeddee relationship. - if (connection_) - CHECK_EQ(child->connection(), connection_); - LocalRemoveChild(child); - if (connection_) { - static_cast<ViewTreeClientImpl*>(connection_) - ->RemoveChild(child->id(), id_); - } -} - -void View::MoveToFront() { - if (!parent_ || parent_->children_.back() == this) - return; - Reorder(parent_->children_.back(), mojo::ORDER_DIRECTION_ABOVE); -} - -void View::MoveToBack() { - if (!parent_ || parent_->children_.front() == this) - return; - Reorder(parent_->children_.front(), mojo::ORDER_DIRECTION_BELOW); -} - -void View::Reorder(View* relative, mojo::OrderDirection direction) { - if (!LocalReorder(relative, direction)) - return; - if (connection_) { - static_cast<ViewTreeClientImpl*>(connection_) - ->Reorder(id_, relative->id(), direction); - } -} - -bool View::Contains(View* child) const { - if (!child) - return false; - if (child == this) - return true; - if (connection_) - CHECK_EQ(child->connection(), connection_); - for (View* p = child->parent(); p; p = p->parent()) { - if (p == this) - return true; - } - return false; -} - -View* View::GetChildById(Id id) { - if (id == id_) - return this; - // TODO(beng): this could be improved depending on how we decide to own views. - Children::const_iterator it = children_.begin(); - for (; it != children_.end(); ++it) { - View* view = (*it)->GetChildById(id); - if (view) - return view; - } - return NULL; -} - -void View::SetTextInputState(mojo::TextInputStatePtr state) { - if (connection_) { - static_cast<ViewTreeClientImpl*>(connection_) - ->SetViewTextInputState(id_, state.Pass()); - } -} - -void View::SetImeVisibility(bool visible, mojo::TextInputStatePtr state) { - // SetImeVisibility() shouldn't be used if the view is not editable. - DCHECK(state.is_null() || state->type != mojo::TEXT_INPUT_TYPE_NONE); - if (connection_) { - static_cast<ViewTreeClientImpl*>(connection_) - ->SetImeVisibility(id_, visible, state.Pass()); - } -} - -void View::SetFocus() { - if (connection_) - static_cast<ViewTreeClientImpl*>(connection_)->SetFocus(id_); -} - -bool View::HasFocus() const { - return connection_ && connection_->GetFocusedView() == this; -} - -void View::Embed(mojo::ViewTreeClientPtr client) { - Embed(client.Pass(), mojo::ViewTree::ACCESS_POLICY_DEFAULT, - base::Bind(&EmptyEmbedCallback)); -} - -void View::Embed(mojo::ViewTreeClientPtr client, - uint32_t policy_bitmask, - const EmbedCallback& callback) { - if (PrepareForEmbed()) { - static_cast<ViewTreeClientImpl*>(connection_) - ->Embed(id_, client.Pass(), policy_bitmask, callback); - } else { - callback.Run(false, 0); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// View, protected: - -namespace { - -mojo::ViewportMetricsPtr CreateEmptyViewportMetrics() { - mojo::ViewportMetricsPtr metrics = mojo::ViewportMetrics::New(); - metrics->size_in_pixels = mojo::Size::New(); - // TODO(vtl): The |.Pass()| below is only needed due to an MSVS bug; remove it - // once that's fixed. - return metrics.Pass(); -} - -} // namespace - -View::View() - : connection_(NULL), - id_(static_cast<Id>(-1)), - parent_(NULL), - viewport_metrics_(CreateEmptyViewportMetrics()), - visible_(true), - drawn_(false) {} - -View::~View() { - FOR_EACH_OBSERVER(ViewObserver, observers_, OnViewDestroying(this)); - if (parent_) - parent_->LocalRemoveChild(this); - - // We may still have children. This can happen if the embedder destroys the - // root while we're still alive. - while (!children_.empty()) { - View* child = children_.front(); - LocalRemoveChild(child); - DCHECK(children_.empty() || children_.front() != child); - } - - // TODO(beng): It'd be better to do this via a destruction observer in the - // ViewTreeClientImpl. - if (connection_) - static_cast<ViewTreeClientImpl*>(connection_)->RemoveView(id_); - - // Clear properties. - for (auto& pair : prop_map_) { - if (pair.second.deallocator) - (*pair.second.deallocator)(pair.second.value); - } - prop_map_.clear(); - - FOR_EACH_OBSERVER(ViewObserver, observers_, OnViewDestroyed(this)); - - if (connection_ && connection_->GetRoot() == this) - static_cast<ViewTreeClientImpl*>(connection_)->OnRootDestroyed(this); -} - -//////////////////////////////////////////////////////////////////////////////// -// View, private: - -View::View(ViewTreeConnection* connection, Id id) - : connection_(connection), - id_(id), - parent_(nullptr), - viewport_metrics_(CreateEmptyViewportMetrics()), - visible_(false), - drawn_(false) {} - -int64 View::SetLocalPropertyInternal(const void* key, - const char* name, - PropertyDeallocator deallocator, - int64 value, - int64 default_value) { - int64 old = GetLocalPropertyInternal(key, default_value); - if (value == default_value) { - prop_map_.erase(key); - } else { - Value prop_value; - prop_value.name = name; - prop_value.value = value; - prop_value.deallocator = deallocator; - prop_map_[key] = prop_value; - } - FOR_EACH_OBSERVER(ViewObserver, observers_, - OnViewLocalPropertyChanged(this, key, old)); - return old; -} - -int64 View::GetLocalPropertyInternal(const void* key, - int64 default_value) const { - std::map<const void*, Value>::const_iterator iter = prop_map_.find(key); - if (iter == prop_map_.end()) - return default_value; - return iter->second.value; -} - -void View::LocalDestroy() { - delete this; -} - -void View::LocalAddChild(View* child) { - ScopedTreeNotifier notifier(child, child->parent(), this); - if (child->parent()) - RemoveChildImpl(child, &child->parent_->children_); - children_.push_back(child); - child->parent_ = this; -} - -void View::LocalRemoveChild(View* child) { - DCHECK_EQ(this, child->parent()); - ScopedTreeNotifier notifier(child, this, NULL); - RemoveChildImpl(child, &children_); -} - -bool View::LocalReorder(View* relative, mojo::OrderDirection direction) { - return ReorderImpl(&parent_->children_, this, relative, direction); -} - -void View::LocalSetBounds(const mojo::Rect& old_bounds, - const mojo::Rect& new_bounds) { - DCHECK(old_bounds.x == bounds_.x); - DCHECK(old_bounds.y == bounds_.y); - DCHECK(old_bounds.width == bounds_.width); - DCHECK(old_bounds.height == bounds_.height); - ScopedSetBoundsNotifier notifier(this, old_bounds, new_bounds); - bounds_ = new_bounds; -} - -void View::LocalSetViewportMetrics(const mojo::ViewportMetrics& old_metrics, - const mojo::ViewportMetrics& new_metrics) { - // TODO(eseidel): We could check old_metrics against viewport_metrics_. - viewport_metrics_ = new_metrics.Clone(); - FOR_EACH_OBSERVER( - ViewObserver, observers_, - OnViewViewportMetricsChanged(this, old_metrics, new_metrics)); -} - -void View::LocalSetDrawn(bool value) { - if (drawn_ == value) - return; - - // As IsDrawn() is derived from |visible_| and |drawn_|, only send drawn - // notification is the value of IsDrawn() is really changing. - if (IsDrawn() == value) { - drawn_ = value; - return; - } - FOR_EACH_OBSERVER(ViewObserver, observers_, OnViewDrawnChanging(this)); - drawn_ = value; - FOR_EACH_OBSERVER(ViewObserver, observers_, OnViewDrawnChanged(this)); -} - -void View::LocalSetVisible(bool visible) { - if (visible_ == visible) - return; - - FOR_EACH_OBSERVER(ViewObserver, observers_, OnViewVisibilityChanging(this)); - visible_ = visible; - NotifyViewVisibilityChanged(this); -} - -void View::NotifyViewVisibilityChanged(View* target) { - if (!NotifyViewVisibilityChangedDown(target)) { - return; // |this| has been deleted. - } - NotifyViewVisibilityChangedUp(target); -} - -bool View::NotifyViewVisibilityChangedAtReceiver(View* target) { - // |this| may be deleted during a call to OnViewVisibilityChanged() on one - // of the observers. We create an local observer for that. In that case we - // exit without further access to any members. - ViewTracker tracker; - tracker.Add(this); - FOR_EACH_OBSERVER(ViewObserver, observers_, OnViewVisibilityChanged(target)); - return tracker.Contains(this); -} - -bool View::NotifyViewVisibilityChangedDown(View* target) { - if (!NotifyViewVisibilityChangedAtReceiver(target)) - return false; // |this| was deleted. - std::set<const View*> child_already_processed; - bool child_destroyed = false; - do { - child_destroyed = false; - for (View::Children::const_iterator it = children_.begin(); - it != children_.end(); ++it) { - if (!child_already_processed.insert(*it).second) - continue; - if (!(*it)->NotifyViewVisibilityChangedDown(target)) { - // |*it| was deleted, |it| is invalid and |children_| has changed. We - // exit the current for-loop and enter a new one. - child_destroyed = true; - break; - } - } - } while (child_destroyed); - return true; -} - -void View::NotifyViewVisibilityChangedUp(View* target) { - // Start with the parent as we already notified |this| - // in NotifyViewVisibilityChangedDown. - for (View* view = parent(); view; view = view->parent()) { - bool ret = view->NotifyViewVisibilityChangedAtReceiver(target); - DCHECK(ret); - } -} - -bool View::PrepareForEmbed() { - if (!OwnsView(connection_, this) && - !static_cast<ViewTreeClientImpl*>(connection_)->is_embed_root()) { - return false; - } - - while (!children_.empty()) - RemoveChild(children_[0]); - return true; -} - -} // namespace mus
diff --git a/components/mus/public/cpp/lib/view_private.cc b/components/mus/public/cpp/lib/view_private.cc deleted file mode 100644 index 8cee1cc..0000000 --- a/components/mus/public/cpp/lib/view_private.cc +++ /dev/null
@@ -1,20 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/mus/public/cpp/lib/view_private.h" - -namespace mus { - -ViewPrivate::ViewPrivate(View* view) : view_(view) { - CHECK(view); -} - -ViewPrivate::~ViewPrivate() {} - -// static -View* ViewPrivate::LocalCreate() { - return new View; -} - -} // namespace mus
diff --git a/components/mus/public/cpp/lib/view_private.h b/components/mus/public/cpp/lib/view_private.h deleted file mode 100644 index 56b20aa..0000000 --- a/components/mus/public/cpp/lib/view_private.h +++ /dev/null
@@ -1,66 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_MUS_PUBLIC_CPP_LIB_VIEW_PRIVATE_H_ -#define COMPONENTS_MUS_PUBLIC_CPP_LIB_VIEW_PRIVATE_H_ - -#include "components/mus/public/cpp/view.h" - -namespace mus { - -// This class is a friend of a View and contains functions to mutate internal -// state of View. -class ViewPrivate { - public: - explicit ViewPrivate(View* view); - ~ViewPrivate(); - - // Creates and returns a new View. Caller owns the return value. - static View* LocalCreate(); - - base::ObserverList<ViewObserver>* observers() { return &view_->observers_; } - - void ClearParent() { view_->parent_ = NULL; } - - void set_visible(bool visible) { view_->visible_ = visible; } - - void set_drawn(bool drawn) { view_->drawn_ = drawn; } - - void set_id(Id id) { view_->id_ = id; } - - void set_connection(ViewTreeConnection* connection) { - view_->connection_ = connection; - } - - void set_properties(const std::map<std::string, std::vector<uint8_t>>& data) { - view_->properties_ = data; - } - - void LocalSetViewportMetrics(const mojo::ViewportMetrics& old_metrics, - const mojo::ViewportMetrics& new_metrics) { - view_->LocalSetViewportMetrics(new_metrics, new_metrics); - } - - void LocalDestroy() { view_->LocalDestroy(); } - void LocalAddChild(View* child) { view_->LocalAddChild(child); } - void LocalRemoveChild(View* child) { view_->LocalRemoveChild(child); } - void LocalReorder(View* relative, mojo::OrderDirection direction) { - view_->LocalReorder(relative, direction); - } - void LocalSetBounds(const mojo::Rect& old_bounds, - const mojo::Rect& new_bounds) { - view_->LocalSetBounds(old_bounds, new_bounds); - } - void LocalSetDrawn(bool drawn) { view_->LocalSetDrawn(drawn); } - void LocalSetVisible(bool visible) { view_->LocalSetVisible(visible); } - - private: - View* view_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(ViewPrivate); -}; - -} // namespace mus - -#endif // COMPONENTS_MUS_PUBLIC_CPP_LIB_VIEW_PRIVATE_H_
diff --git a/components/mus/public/cpp/lib/view_tree_client_impl.cc b/components/mus/public/cpp/lib/view_tree_client_impl.cc deleted file mode 100644 index bd2a8eb..0000000 --- a/components/mus/public/cpp/lib/view_tree_client_impl.cc +++ /dev/null
@@ -1,449 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/mus/public/cpp/lib/view_tree_client_impl.h" - -#include "components/mus/public/cpp/lib/view_private.h" -#include "components/mus/public/cpp/util.h" -#include "components/mus/public/cpp/view_observer.h" -#include "components/mus/public/cpp/view_tree_connection.h" -#include "components/mus/public/cpp/view_tree_delegate.h" -#include "mojo/application/public/cpp/application_impl.h" -#include "mojo/application/public/cpp/connect.h" -#include "mojo/application/public/cpp/service_provider_impl.h" -#include "mojo/application/public/interfaces/service_provider.mojom.h" - -namespace mus { - -Id MakeTransportId(ConnectionSpecificId connection_id, - ConnectionSpecificId local_id) { - return (connection_id << 16) | local_id; -} - -// Helper called to construct a local view object from transport data. -View* AddViewToConnection(ViewTreeClientImpl* client, - View* parent, - const mojo::ViewDataPtr& view_data) { - // We don't use the cto that takes a ViewTreeConnection here, since it will - // call back to the service and attempt to create a new view. - View* view = ViewPrivate::LocalCreate(); - ViewPrivate private_view(view); - private_view.set_connection(client); - private_view.set_id(view_data->view_id); - private_view.set_visible(view_data->visible); - private_view.set_drawn(view_data->drawn); - private_view.LocalSetViewportMetrics(mojo::ViewportMetrics(), - *view_data->viewport_metrics); - private_view.set_properties( - view_data->properties.To<std::map<std::string, std::vector<uint8_t>>>()); - client->AddView(view); - private_view.LocalSetBounds(mojo::Rect(), *view_data->bounds); - if (parent) - ViewPrivate(parent).LocalAddChild(view); - return view; -} - -View* BuildViewTree(ViewTreeClientImpl* client, - const mojo::Array<mojo::ViewDataPtr>& views, - View* initial_parent) { - std::vector<View*> parents; - View* root = NULL; - View* last_view = NULL; - if (initial_parent) - parents.push_back(initial_parent); - for (size_t i = 0; i < views.size(); ++i) { - if (last_view && views[i]->parent_id == last_view->id()) { - parents.push_back(last_view); - } else if (!parents.empty()) { - while (parents.back()->id() != views[i]->parent_id) - parents.pop_back(); - } - View* view = AddViewToConnection( - client, !parents.empty() ? parents.back() : NULL, views[i]); - if (!last_view) - root = view; - last_view = view; - } - return root; -} - -ViewTreeConnection* ViewTreeConnection::Create( - ViewTreeDelegate* delegate, - mojo::InterfaceRequest<mojo::ViewTreeClient> request, - CreateType create_type) { - ViewTreeClientImpl* client = new ViewTreeClientImpl(delegate, request.Pass()); - if (create_type == CreateType::WAIT_FOR_EMBED) - client->WaitForEmbed(); - return client; -} - -ViewTreeClientImpl::ViewTreeClientImpl( - ViewTreeDelegate* delegate, - mojo::InterfaceRequest<mojo::ViewTreeClient> request) - : connection_id_(0), - next_id_(1), - delegate_(delegate), - root_(nullptr), - capture_view_(nullptr), - focused_view_(nullptr), - activated_view_(nullptr), - binding_(this, request.Pass()), - is_embed_root_(false), - in_destructor_(false) {} - -ViewTreeClientImpl::~ViewTreeClientImpl() { - in_destructor_ = true; - - std::vector<View*> non_owned; - while (!views_.empty()) { - IdToViewMap::iterator it = views_.begin(); - if (OwnsView(it->second->id())) { - it->second->Destroy(); - } else { - non_owned.push_back(it->second); - views_.erase(it); - } - } - - // Delete the non-owned views last. In the typical case these are roots. The - // exception is the window manager and embed roots, which may know about - // other random views that it doesn't own. - // NOTE: we manually delete as we're a friend. - for (size_t i = 0; i < non_owned.size(); ++i) - delete non_owned[i]; - - delegate_->OnConnectionLost(this); -} - -void ViewTreeClientImpl::WaitForEmbed() { - DCHECK(!root_); - // OnEmbed() is the first function called. - binding_.WaitForIncomingMethodCall(); - // TODO(sky): deal with pipe being closed before we get OnEmbed(). -} - -void ViewTreeClientImpl::DestroyView(Id view_id) { - DCHECK(tree_); - tree_->DeleteView(view_id, ActionCompletedCallback()); -} - -void ViewTreeClientImpl::AddChild(Id child_id, Id parent_id) { - DCHECK(tree_); - tree_->AddView(parent_id, child_id, ActionCompletedCallback()); -} - -void ViewTreeClientImpl::RemoveChild(Id child_id, Id parent_id) { - DCHECK(tree_); - tree_->RemoveViewFromParent(child_id, ActionCompletedCallback()); -} - -void ViewTreeClientImpl::Reorder(Id view_id, - Id relative_view_id, - mojo::OrderDirection direction) { - DCHECK(tree_); - tree_->ReorderView(view_id, relative_view_id, direction, - ActionCompletedCallback()); -} - -bool ViewTreeClientImpl::OwnsView(Id id) const { - return HiWord(id) == connection_id_; -} - -void ViewTreeClientImpl::SetBounds(Id view_id, const mojo::Rect& bounds) { - DCHECK(tree_); - tree_->SetViewBounds(view_id, bounds.Clone(), ActionCompletedCallback()); -} - -void ViewTreeClientImpl::SetFocus(Id view_id) { - // In order for us to get here we had to have exposed a view, which implies we - // got a connection. - DCHECK(tree_); - tree_->SetFocus(view_id); -} - -void ViewTreeClientImpl::SetVisible(Id view_id, bool visible) { - DCHECK(tree_); - tree_->SetViewVisibility(view_id, visible, ActionCompletedCallback()); -} - -void ViewTreeClientImpl::SetProperty(Id view_id, - const std::string& name, - const std::vector<uint8_t>& data) { - DCHECK(tree_); - tree_->SetViewProperty(view_id, mojo::String(name), - mojo::Array<uint8_t>::From(data), - ActionCompletedCallback()); -} - -void ViewTreeClientImpl::SetViewTextInputState(Id view_id, - mojo::TextInputStatePtr state) { - DCHECK(tree_); - tree_->SetViewTextInputState(view_id, state.Pass()); -} - -void ViewTreeClientImpl::SetImeVisibility(Id view_id, - bool visible, - mojo::TextInputStatePtr state) { - DCHECK(tree_); - tree_->SetImeVisibility(view_id, visible, state.Pass()); -} - -void ViewTreeClientImpl::Embed(Id view_id, - mojo::ViewTreeClientPtr client, - uint32_t policy_bitmask, - const mojo::ViewTree::EmbedCallback& callback) { - DCHECK(tree_); - tree_->Embed(view_id, client.Pass(), policy_bitmask, callback); -} - -void ViewTreeClientImpl::RequestSurface( - Id view_id, - mojo::InterfaceRequest<mojo::Surface> surface, - mojo::SurfaceClientPtr client) { - DCHECK(tree_); - tree_->RequestSurface(view_id, surface.Pass(), client.Pass()); -} - -void ViewTreeClientImpl::AddView(View* view) { - DCHECK(views_.find(view->id()) == views_.end()); - views_[view->id()] = view; -} - -void ViewTreeClientImpl::RemoveView(Id view_id) { - if (focused_view_ && focused_view_->id() == view_id) - OnViewFocused(0); - - IdToViewMap::iterator it = views_.find(view_id); - if (it != views_.end()) - views_.erase(it); -} - -void ViewTreeClientImpl::OnRootDestroyed(View* root) { - DCHECK_EQ(root, root_); - root_ = nullptr; - - // When the root is gone we can't do anything useful. - if (!in_destructor_) - delete this; -} - -//////////////////////////////////////////////////////////////////////////////// -// ViewTreeClientImpl, ViewTreeConnection implementation: - -Id ViewTreeClientImpl::CreateViewOnServer() { - DCHECK(tree_); - const Id view_id = MakeTransportId(connection_id_, next_id_++); - tree_->CreateView(view_id, [this](mojo::ErrorCode code) { - OnActionCompleted(code == mojo::ERROR_CODE_NONE); - }); - return view_id; -} - -View* ViewTreeClientImpl::GetRoot() { - return root_; -} - -View* ViewTreeClientImpl::GetViewById(Id id) { - IdToViewMap::const_iterator it = views_.find(id); - return it != views_.end() ? it->second : NULL; -} - -View* ViewTreeClientImpl::GetFocusedView() { - return focused_view_; -} - -View* ViewTreeClientImpl::CreateView() { - View* view = new View(this, CreateViewOnServer()); - AddView(view); - return view; -} - -bool ViewTreeClientImpl::IsEmbedRoot() { - return is_embed_root_; -} - -ConnectionSpecificId ViewTreeClientImpl::GetConnectionId() { - return connection_id_; -} - -//////////////////////////////////////////////////////////////////////////////// -// ViewTreeClientImpl, ViewTreeClient implementation: - -void ViewTreeClientImpl::OnEmbed(ConnectionSpecificId connection_id, - mojo::ViewDataPtr root_data, - mojo::ViewTreePtr tree, - Id focused_view_id, - uint32 access_policy) { - if (tree) { - DCHECK(!tree_); - tree_ = tree.Pass(); - tree_.set_connection_error_handler([this]() { delete this; }); - } - connection_id_ = connection_id; - is_embed_root_ = - (access_policy & mojo::ViewTree::ACCESS_POLICY_EMBED_ROOT) != 0; - - DCHECK(!root_); - root_ = AddViewToConnection(this, nullptr, root_data); - - focused_view_ = GetViewById(focused_view_id); - - delegate_->OnEmbed(root_); -} - -void ViewTreeClientImpl::OnEmbeddedAppDisconnected(Id view_id) { - View* view = GetViewById(view_id); - if (view) { - FOR_EACH_OBSERVER(ViewObserver, *ViewPrivate(view).observers(), - OnViewEmbeddedAppDisconnected(view)); - } -} - -void ViewTreeClientImpl::OnUnembed() { - delegate_->OnUnembed(); - // This will send out the various notifications. - delete this; -} - -void ViewTreeClientImpl::OnViewBoundsChanged(Id view_id, - mojo::RectPtr old_bounds, - mojo::RectPtr new_bounds) { - View* view = GetViewById(view_id); - ViewPrivate(view).LocalSetBounds(*old_bounds, *new_bounds); -} - -namespace { - -void SetViewportMetricsOnDecendants(View* root, - const mojo::ViewportMetrics& old_metrics, - const mojo::ViewportMetrics& new_metrics) { - ViewPrivate(root).LocalSetViewportMetrics(old_metrics, new_metrics); - const View::Children& children = root->children(); - for (size_t i = 0; i < children.size(); ++i) - SetViewportMetricsOnDecendants(children[i], old_metrics, new_metrics); -} -} - -void ViewTreeClientImpl::OnViewViewportMetricsChanged( - mojo::ViewportMetricsPtr old_metrics, - mojo::ViewportMetricsPtr new_metrics) { - View* view = GetRoot(); - if (view) - SetViewportMetricsOnDecendants(view, *old_metrics, *new_metrics); -} - -void ViewTreeClientImpl::OnViewHierarchyChanged( - Id view_id, - Id new_parent_id, - Id old_parent_id, - mojo::Array<mojo::ViewDataPtr> views) { - View* initial_parent = views.size() ? GetViewById(views[0]->parent_id) : NULL; - - const bool was_view_known = GetViewById(view_id) != nullptr; - - BuildViewTree(this, views, initial_parent); - - // If the view was not known, then BuildViewTree() will have created it and - // parented the view. - if (!was_view_known) - return; - - View* new_parent = GetViewById(new_parent_id); - View* old_parent = GetViewById(old_parent_id); - View* view = GetViewById(view_id); - if (new_parent) - ViewPrivate(new_parent).LocalAddChild(view); - else - ViewPrivate(old_parent).LocalRemoveChild(view); -} - -void ViewTreeClientImpl::OnViewReordered(Id view_id, - Id relative_view_id, - mojo::OrderDirection direction) { - View* view = GetViewById(view_id); - View* relative_view = GetViewById(relative_view_id); - if (view && relative_view) - ViewPrivate(view).LocalReorder(relative_view, direction); -} - -void ViewTreeClientImpl::OnViewDeleted(Id view_id) { - View* view = GetViewById(view_id); - if (view) - ViewPrivate(view).LocalDestroy(); -} - -void ViewTreeClientImpl::OnViewVisibilityChanged(Id view_id, bool visible) { - // TODO(sky): there is a race condition here. If this client and another - // client change the visibility at the same time the wrong value may be set. - // Deal with this some how. - View* view = GetViewById(view_id); - if (view) - ViewPrivate(view).LocalSetVisible(visible); -} - -void ViewTreeClientImpl::OnViewDrawnStateChanged(Id view_id, bool drawn) { - View* view = GetViewById(view_id); - if (view) - ViewPrivate(view).LocalSetDrawn(drawn); -} - -void ViewTreeClientImpl::OnViewSharedPropertyChanged( - Id view_id, - const mojo::String& name, - mojo::Array<uint8_t> new_data) { - View* view = GetViewById(view_id); - if (view) { - std::vector<uint8_t> data; - std::vector<uint8_t>* data_ptr = NULL; - if (!new_data.is_null()) { - data = new_data.To<std::vector<uint8_t>>(); - data_ptr = &data; - } - - view->SetSharedProperty(name, data_ptr); - } -} - -void ViewTreeClientImpl::OnViewInputEvent( - Id view_id, - mojo::EventPtr event, - const mojo::Callback<void()>& ack_callback) { - View* view = GetViewById(view_id); - if (view) { - FOR_EACH_OBSERVER(ViewObserver, *ViewPrivate(view).observers(), - OnViewInputEvent(view, event)); - } - ack_callback.Run(); -} - -void ViewTreeClientImpl::OnViewFocused(Id focused_view_id) { - View* focused = GetViewById(focused_view_id); - View* blurred = focused_view_; - // Update |focused_view_| before calling any of the observers, so that the - // observers get the correct result from calling |View::HasFocus()|, - // |ViewTreeConnection::GetFocusedView()| etc. - focused_view_ = focused; - if (blurred) { - FOR_EACH_OBSERVER(ViewObserver, *ViewPrivate(blurred).observers(), - OnViewFocusChanged(focused, blurred)); - } - if (focused) { - FOR_EACH_OBSERVER(ViewObserver, *ViewPrivate(focused).observers(), - OnViewFocusChanged(focused, blurred)); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// ViewTreeClientImpl, private: - -void ViewTreeClientImpl::OnActionCompleted(bool success) { - if (!change_acked_callback_.is_null()) - change_acked_callback_.Run(); -} - -mojo::Callback<void(bool)> ViewTreeClientImpl::ActionCompletedCallback() { - return [this](bool success) { OnActionCompleted(success); }; -} - -} // namespace mus
diff --git a/components/mus/public/cpp/lib/view_tree_client_impl.h b/components/mus/public/cpp/lib/view_tree_client_impl.h deleted file mode 100644 index b532c735..0000000 --- a/components/mus/public/cpp/lib/view_tree_client_impl.h +++ /dev/null
@@ -1,162 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_MUS_PUBLIC_CPP_LIB_VIEW_TREE_CLIENT_IMPL_H_ -#define COMPONENTS_MUS_PUBLIC_CPP_LIB_VIEW_TREE_CLIENT_IMPL_H_ - -#include "components/mus/public/cpp/types.h" -#include "components/mus/public/cpp/view.h" -#include "components/mus/public/cpp/view_tree_connection.h" -#include "components/mus/public/interfaces/view_tree.mojom.h" -#include "third_party/mojo/src/mojo/public/cpp/bindings/strong_binding.h" - -namespace mus { -class ViewTreeConnection; -class ViewTreeDelegate; - -// Manages the connection with the View Manager service. -class ViewTreeClientImpl : public ViewTreeConnection, - public mojo::ViewTreeClient { - public: - ViewTreeClientImpl(ViewTreeDelegate* delegate, - mojo::InterfaceRequest<mojo::ViewTreeClient> request); - ~ViewTreeClientImpl() override; - - // Wait for OnEmbed(), returning when done. - void WaitForEmbed(); - - bool connected() const { return tree_; } - ConnectionSpecificId connection_id() const { return connection_id_; } - - // API exposed to the view implementations that pushes local changes to the - // service. - void DestroyView(Id view_id); - - // These methods take TransportIds. For views owned by the current connection, - // the connection id high word can be zero. In all cases, the TransportId 0x1 - // refers to the root view. - void AddChild(Id child_id, Id parent_id); - void RemoveChild(Id child_id, Id parent_id); - - void Reorder(Id view_id, Id relative_view_id, mojo::OrderDirection direction); - - // Returns true if the specified view was created by this connection. - bool OwnsView(Id id) const; - - void SetBounds(Id view_id, const mojo::Rect& bounds); - void SetFocus(Id view_id); - void SetVisible(Id view_id, bool visible); - void SetProperty(Id view_id, - const std::string& name, - const std::vector<uint8_t>& data); - void SetViewTextInputState(Id view_id, mojo::TextInputStatePtr state); - void SetImeVisibility(Id view_id, - bool visible, - mojo::TextInputStatePtr state); - - void Embed(Id view_id, - mojo::ViewTreeClientPtr client, - uint32_t policy_bitmask, - const mojo::ViewTree::EmbedCallback& callback); - - void RequestSurface(Id view_id, - mojo::InterfaceRequest<mojo::Surface> surface, - mojo::SurfaceClientPtr client); - - void set_change_acked_callback(const mojo::Callback<void(void)>& callback) { - change_acked_callback_ = callback; - } - void ClearChangeAckedCallback() { change_acked_callback_.reset(); } - - // Start/stop tracking views. While tracked, they can be retrieved via - // ViewTreeConnection::GetViewById. - void AddView(View* view); - void RemoveView(Id view_id); - - bool is_embed_root() const { return is_embed_root_; } - - // Called after the root view's observers have been notified of destruction - // (as the last step of ~View). This ordering ensures that the View Manager - // is torn down after the root. - void OnRootDestroyed(View* root); - - private: - typedef std::map<Id, View*> IdToViewMap; - - Id CreateViewOnServer(); - - // Overridden from ViewTreeConnection: - View* GetRoot() override; - View* GetViewById(Id id) override; - View* GetFocusedView() override; - View* CreateView() override; - bool IsEmbedRoot() override; - ConnectionSpecificId GetConnectionId() override; - - // Overridden from ViewTreeClient: - void OnEmbed(ConnectionSpecificId connection_id, - mojo::ViewDataPtr root, - mojo::ViewTreePtr tree, - Id focused_view_id, - uint32_t access_policy) override; - void OnEmbeddedAppDisconnected(Id view_id) override; - void OnUnembed() override; - void OnViewBoundsChanged(Id view_id, - mojo::RectPtr old_bounds, - mojo::RectPtr new_bounds) override; - void OnViewViewportMetricsChanged( - mojo::ViewportMetricsPtr old_metrics, - mojo::ViewportMetricsPtr new_metrics) override; - void OnViewHierarchyChanged(Id view_id, - Id new_parent_id, - Id old_parent_id, - mojo::Array<mojo::ViewDataPtr> views) override; - void OnViewReordered(Id view_id, - Id relative_view_id, - mojo::OrderDirection direction) override; - void OnViewDeleted(Id view_id) override; - void OnViewVisibilityChanged(Id view_id, bool visible) override; - void OnViewDrawnStateChanged(Id view_id, bool drawn) override; - void OnViewSharedPropertyChanged(Id view_id, - const mojo::String& name, - mojo::Array<uint8_t> new_data) override; - void OnViewInputEvent(Id view_id, - mojo::EventPtr event, - const mojo::Callback<void()>& callback) override; - void OnViewFocused(Id focused_view_id) override; - - void RootDestroyed(View* root); - - void OnActionCompleted(bool success); - - mojo::Callback<void(bool)> ActionCompletedCallback(); - - ConnectionSpecificId connection_id_; - ConnectionSpecificId next_id_; - - mojo::Callback<void(void)> change_acked_callback_; - - ViewTreeDelegate* delegate_; - - View* root_; - - IdToViewMap views_; - - View* capture_view_; - View* focused_view_; - View* activated_view_; - - mojo::Binding<ViewTreeClient> binding_; - mojo::ViewTreePtr tree_; - - bool is_embed_root_; - - bool in_destructor_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(ViewTreeClientImpl); -}; - -} // namespace mus - -#endif // COMPONENTS_MUS_PUBLIC_CPP_LIB_VIEW_TREE_CLIENT_IMPL_H_
diff --git a/components/mus/public/cpp/lib/view_tree_host_factory.cc b/components/mus/public/cpp/lib/view_tree_host_factory.cc deleted file mode 100644 index 4f649fe..0000000 --- a/components/mus/public/cpp/lib/view_tree_host_factory.cc +++ /dev/null
@@ -1,36 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/mus/public/cpp/view_tree_host_factory.h" - -#include "components/mus/public/cpp/view_tree_connection.h" -#include "components/mus/public/cpp/view_tree_delegate.h" -#include "mojo/application/public/cpp/application_impl.h" - -namespace mus { - -void CreateViewTreeHost(mojo::ViewTreeHostFactory* factory, - mojo::ViewTreeHostClientPtr host_client, - ViewTreeDelegate* delegate, - mojo::ViewTreeHostPtr* host) { - mojo::ViewTreeClientPtr tree_client; - ViewTreeConnection::Create( - delegate, GetProxy(&tree_client), - ViewTreeConnection::CreateType::DONT_WAIT_FOR_EMBED); - factory->CreateViewTreeHost(GetProxy(host), host_client.Pass(), - tree_client.Pass()); -} - -void CreateSingleViewTreeHost(mojo::ApplicationImpl* app, - ViewTreeDelegate* delegate, - mojo::ViewTreeHostPtr* host) { - mojo::ViewTreeHostFactoryPtr factory; - mojo::URLRequestPtr request(mojo::URLRequest::New()); - request->url = "mojo:mus"; - app->ConnectToService(request.Pass(), &factory); - CreateViewTreeHost(factory.get(), mojo::ViewTreeHostClientPtr(), delegate, - host); -} - -} // namespace mus
diff --git a/components/mus/public/cpp/lib/window.cc b/components/mus/public/cpp/lib/window.cc new file mode 100644 index 0000000..eb4f8ca --- /dev/null +++ b/components/mus/public/cpp/lib/window.cc
@@ -0,0 +1,623 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/mus/public/cpp/window.h" + +#include <set> +#include <string> + +#include "base/bind.h" +#include "components/mus/public/cpp/lib/window_private.h" +#include "components/mus/public/cpp/lib/window_tree_client_impl.h" +#include "components/mus/public/cpp/window_observer.h" +#include "components/mus/public/cpp/window_surface.h" +#include "components/mus/public/cpp/window_tracker.h" +#include "mojo/application/public/cpp/service_provider_impl.h" + +namespace mus { + +namespace { + +void NotifyWindowTreeChangeAtReceiver( + Window* receiver, + const WindowObserver::TreeChangeParams& params, + bool change_applied) { + WindowObserver::TreeChangeParams local_params = params; + local_params.receiver = receiver; + if (change_applied) { + FOR_EACH_OBSERVER(WindowObserver, *WindowPrivate(receiver).observers(), + OnTreeChanged(local_params)); + } else { + FOR_EACH_OBSERVER(WindowObserver, *WindowPrivate(receiver).observers(), + OnTreeChanging(local_params)); + } +} + +void NotifyWindowTreeChangeUp(Window* start_at, + const WindowObserver::TreeChangeParams& params, + bool change_applied) { + for (Window* current = start_at; current; current = current->parent()) + NotifyWindowTreeChangeAtReceiver(current, params, change_applied); +} + +void NotifyWindowTreeChangeDown(Window* start_at, + const WindowObserver::TreeChangeParams& params, + bool change_applied) { + NotifyWindowTreeChangeAtReceiver(start_at, params, change_applied); + Window::Children::const_iterator it = start_at->children().begin(); + for (; it != start_at->children().end(); ++it) + NotifyWindowTreeChangeDown(*it, params, change_applied); +} + +void NotifyWindowTreeChange(const WindowObserver::TreeChangeParams& params, + bool change_applied) { + NotifyWindowTreeChangeDown(params.target, params, change_applied); + if (params.old_parent) + NotifyWindowTreeChangeUp(params.old_parent, params, change_applied); + if (params.new_parent) + NotifyWindowTreeChangeUp(params.new_parent, params, change_applied); +} + +class ScopedTreeNotifier { + public: + ScopedTreeNotifier(Window* target, Window* old_parent, Window* new_parent) { + params_.target = target; + params_.old_parent = old_parent; + params_.new_parent = new_parent; + NotifyWindowTreeChange(params_, false); + } + ~ScopedTreeNotifier() { NotifyWindowTreeChange(params_, true); } + + private: + WindowObserver::TreeChangeParams params_; + + MOJO_DISALLOW_COPY_AND_ASSIGN(ScopedTreeNotifier); +}; + +void RemoveChildImpl(Window* child, Window::Children* children) { + Window::Children::iterator it = + std::find(children->begin(), children->end(), child); + if (it != children->end()) { + children->erase(it); + WindowPrivate(child).ClearParent(); + } +} + +class ScopedOrderChangedNotifier { + public: + ScopedOrderChangedNotifier(Window* window, + Window* relative_window, + mojo::OrderDirection direction) + : window_(window), + relative_window_(relative_window), + direction_(direction) { + FOR_EACH_OBSERVER( + WindowObserver, *WindowPrivate(window_).observers(), + OnWindowReordering(window_, relative_window_, direction_)); + } + ~ScopedOrderChangedNotifier() { + FOR_EACH_OBSERVER(WindowObserver, *WindowPrivate(window_).observers(), + OnWindowReordered(window_, relative_window_, direction_)); + } + + private: + Window* window_; + Window* relative_window_; + mojo::OrderDirection direction_; + + MOJO_DISALLOW_COPY_AND_ASSIGN(ScopedOrderChangedNotifier); +}; + +// Returns true if the order actually changed. +bool ReorderImpl(Window::Children* children, + Window* window, + Window* relative, + mojo::OrderDirection direction) { + DCHECK(relative); + DCHECK_NE(window, relative); + DCHECK_EQ(window->parent(), relative->parent()); + + const size_t child_i = + std::find(children->begin(), children->end(), window) - children->begin(); + const size_t target_i = + std::find(children->begin(), children->end(), relative) - + children->begin(); + if ((direction == mojo::ORDER_DIRECTION_ABOVE && child_i == target_i + 1) || + (direction == mojo::ORDER_DIRECTION_BELOW && child_i + 1 == target_i)) { + return false; + } + + ScopedOrderChangedNotifier notifier(window, relative, direction); + + const size_t dest_i = direction == mojo::ORDER_DIRECTION_ABOVE + ? (child_i < target_i ? target_i : target_i + 1) + : (child_i < target_i ? target_i - 1 : target_i); + children->erase(children->begin() + child_i); + children->insert(children->begin() + dest_i, window); + + return true; +} + +class ScopedSetBoundsNotifier { + public: + ScopedSetBoundsNotifier(Window* window, + const mojo::Rect& old_bounds, + const mojo::Rect& new_bounds) + : window_(window), old_bounds_(old_bounds), new_bounds_(new_bounds) { + FOR_EACH_OBSERVER( + WindowObserver, *WindowPrivate(window_).observers(), + OnWindowBoundsChanging(window_, old_bounds_, new_bounds_)); + } + ~ScopedSetBoundsNotifier() { + FOR_EACH_OBSERVER(WindowObserver, *WindowPrivate(window_).observers(), + OnWindowBoundsChanged(window_, old_bounds_, new_bounds_)); + } + + private: + Window* window_; + const mojo::Rect old_bounds_; + const mojo::Rect new_bounds_; + + MOJO_DISALLOW_COPY_AND_ASSIGN(ScopedSetBoundsNotifier); +}; + +// Some operations are only permitted in the connection that created the window. +bool OwnsWindow(WindowTreeConnection* connection, Window* window) { + return !connection || + static_cast<WindowTreeClientImpl*>(connection) + ->OwnsWindow(window->id()); +} + +void EmptyEmbedCallback(bool result, ConnectionSpecificId connection_id) {} + +} // namespace + +//////////////////////////////////////////////////////////////////////////////// +// Window, public: + +void Window::Destroy() { + if (!OwnsWindow(connection_, this)) + return; + + if (connection_) + static_cast<WindowTreeClientImpl*>(connection_)->DestroyWindow(id_); + while (!children_.empty()) { + Window* child = children_.front(); + if (!OwnsWindow(connection_, child)) { + WindowPrivate(child).ClearParent(); + children_.erase(children_.begin()); + } else { + child->Destroy(); + DCHECK(std::find(children_.begin(), children_.end(), child) == + children_.end()); + } + } + LocalDestroy(); +} + +void Window::SetBounds(const mojo::Rect& bounds) { + if (!OwnsWindow(connection_, this)) + return; + + if (bounds_.Equals(bounds)) + return; + + if (connection_) + static_cast<WindowTreeClientImpl*>(connection_)->SetBounds(id_, bounds); + LocalSetBounds(bounds_, bounds); +} + +void Window::SetVisible(bool value) { + if (visible_ == value) + return; + + if (connection_) + static_cast<WindowTreeClientImpl*>(connection_)->SetVisible(id_, value); + LocalSetVisible(value); +} + +scoped_ptr<WindowSurface> Window::RequestSurface() { + mojo::SurfacePtr surface; + mojo::SurfaceClientPtr client; + mojo::InterfaceRequest<mojo::SurfaceClient> client_request = + GetProxy(&client); + static_cast<WindowTreeClientImpl*>(connection_) + ->RequestSurface(id_, GetProxy(&surface), client.Pass()); + return make_scoped_ptr( + new WindowSurface(surface.PassInterface(), client_request.Pass())); +} + +void Window::SetSharedProperty(const std::string& name, + const std::vector<uint8_t>* value) { + std::vector<uint8_t> old_value; + std::vector<uint8_t>* old_value_ptr = nullptr; + auto it = properties_.find(name); + if (it != properties_.end()) { + old_value = it->second; + old_value_ptr = &old_value; + + if (value && old_value == *value) + return; + } else if (!value) { + // This property isn't set in |properties_| and |value| is NULL, so there's + // no change. + return; + } + + if (value) { + properties_[name] = *value; + } else if (it != properties_.end()) { + properties_.erase(it); + } + + // TODO: add test coverage of this (450303). + if (connection_) { + mojo::Array<uint8_t> transport_value; + if (value) { + transport_value.resize(value->size()); + if (value->size()) + memcpy(&transport_value.front(), &(value->front()), value->size()); + } + static_cast<WindowTreeClientImpl*>(connection_) + ->SetProperty(id_, name, transport_value.Pass()); + } + + FOR_EACH_OBSERVER( + WindowObserver, observers_, + OnWindowSharedPropertyChanged(this, name, old_value_ptr, value)); +} + +bool Window::IsDrawn() const { + if (!visible_) + return false; + return parent_ ? parent_->IsDrawn() : drawn_; +} + +void Window::AddObserver(WindowObserver* observer) { + observers_.AddObserver(observer); +} + +void Window::RemoveObserver(WindowObserver* observer) { + observers_.RemoveObserver(observer); +} + +const Window* Window::GetRoot() const { + const Window* root = this; + for (const Window* parent = this; parent; parent = parent->parent()) + root = parent; + return root; +} + +void Window::AddChild(Window* child) { + // TODO(beng): not necessarily valid to all connections, but possibly to the + // embeddee in an embedder-embeddee relationship. + if (connection_) + CHECK_EQ(child->connection(), connection_); + LocalAddChild(child); + if (connection_) + static_cast<WindowTreeClientImpl*>(connection_)->AddChild(child->id(), id_); +} + +void Window::RemoveChild(Window* child) { + // TODO(beng): not necessarily valid to all connections, but possibly to the + // embeddee in an embedder-embeddee relationship. + if (connection_) + CHECK_EQ(child->connection(), connection_); + LocalRemoveChild(child); + if (connection_) { + static_cast<WindowTreeClientImpl*>(connection_) + ->RemoveChild(child->id(), id_); + } +} + +void Window::MoveToFront() { + if (!parent_ || parent_->children_.back() == this) + return; + Reorder(parent_->children_.back(), mojo::ORDER_DIRECTION_ABOVE); +} + +void Window::MoveToBack() { + if (!parent_ || parent_->children_.front() == this) + return; + Reorder(parent_->children_.front(), mojo::ORDER_DIRECTION_BELOW); +} + +void Window::Reorder(Window* relative, mojo::OrderDirection direction) { + if (!LocalReorder(relative, direction)) + return; + if (connection_) { + static_cast<WindowTreeClientImpl*>(connection_) + ->Reorder(id_, relative->id(), direction); + } +} + +bool Window::Contains(Window* child) const { + if (!child) + return false; + if (child == this) + return true; + if (connection_) + CHECK_EQ(child->connection(), connection_); + for (Window* p = child->parent(); p; p = p->parent()) { + if (p == this) + return true; + } + return false; +} + +Window* Window::GetChildById(Id id) { + if (id == id_) + return this; + // TODO(beng): this could be improved depending on how we decide to own + // windows. + Children::const_iterator it = children_.begin(); + for (; it != children_.end(); ++it) { + Window* window = (*it)->GetChildById(id); + if (window) + return window; + } + return NULL; +} + +void Window::SetTextInputState(mojo::TextInputStatePtr state) { + if (connection_) { + static_cast<WindowTreeClientImpl*>(connection_) + ->SetViewTextInputState(id_, state.Pass()); + } +} + +void Window::SetImeVisibility(bool visible, mojo::TextInputStatePtr state) { + // SetImeVisibility() shouldn't be used if the window is not editable. + DCHECK(state.is_null() || state->type != mojo::TEXT_INPUT_TYPE_NONE); + if (connection_) { + static_cast<WindowTreeClientImpl*>(connection_) + ->SetImeVisibility(id_, visible, state.Pass()); + } +} + +void Window::SetFocus() { + if (connection_) + static_cast<WindowTreeClientImpl*>(connection_)->SetFocus(id_); +} + +bool Window::HasFocus() const { + return connection_ && connection_->GetFocusedWindow() == this; +} + +void Window::Embed(mojo::ViewTreeClientPtr client) { + Embed(client.Pass(), mojo::ViewTree::ACCESS_POLICY_DEFAULT, + base::Bind(&EmptyEmbedCallback)); +} + +void Window::Embed(mojo::ViewTreeClientPtr client, + uint32_t policy_bitmask, + const EmbedCallback& callback) { + if (PrepareForEmbed()) { + static_cast<WindowTreeClientImpl*>(connection_) + ->Embed(id_, client.Pass(), policy_bitmask, callback); + } else { + callback.Run(false, 0); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// Window, protected: + +namespace { + +mojo::ViewportMetricsPtr CreateEmptyViewportMetrics() { + mojo::ViewportMetricsPtr metrics = mojo::ViewportMetrics::New(); + metrics->size_in_pixels = mojo::Size::New(); + // TODO(vtl): The |.Pass()| below is only needed due to an MSVS bug; remove it + // once that's fixed. + return metrics.Pass(); +} + +} // namespace + +Window::Window() + : connection_(NULL), + id_(static_cast<Id>(-1)), + parent_(NULL), + viewport_metrics_(CreateEmptyViewportMetrics()), + visible_(true), + drawn_(false) {} + +Window::~Window() { + FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowDestroying(this)); + if (parent_) + parent_->LocalRemoveChild(this); + + // We may still have children. This can happen if the embedder destroys the + // root while we're still alive. + while (!children_.empty()) { + Window* child = children_.front(); + LocalRemoveChild(child); + DCHECK(children_.empty() || children_.front() != child); + } + + // TODO(beng): It'd be better to do this via a destruction observer in the + // WindowTreeClientImpl. + if (connection_) + static_cast<WindowTreeClientImpl*>(connection_)->RemoveWindow(id_); + + // Clear properties. + for (auto& pair : prop_map_) { + if (pair.second.deallocator) + (*pair.second.deallocator)(pair.second.value); + } + prop_map_.clear(); + + FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowDestroyed(this)); + + if (connection_ && connection_->GetRoot() == this) + static_cast<WindowTreeClientImpl*>(connection_)->OnRootDestroyed(this); +} + +//////////////////////////////////////////////////////////////////////////////// +// View, private: + +Window::Window(WindowTreeConnection* connection, Id id) + : connection_(connection), + id_(id), + parent_(nullptr), + viewport_metrics_(CreateEmptyViewportMetrics()), + visible_(false), + drawn_(false) {} + +int64 Window::SetLocalPropertyInternal(const void* key, + const char* name, + PropertyDeallocator deallocator, + int64 value, + int64 default_value) { + int64 old = GetLocalPropertyInternal(key, default_value); + if (value == default_value) { + prop_map_.erase(key); + } else { + Value prop_value; + prop_value.name = name; + prop_value.value = value; + prop_value.deallocator = deallocator; + prop_map_[key] = prop_value; + } + FOR_EACH_OBSERVER(WindowObserver, observers_, + OnWindowLocalPropertyChanged(this, key, old)); + return old; +} + +int64 Window::GetLocalPropertyInternal(const void* key, + int64 default_value) const { + std::map<const void*, Value>::const_iterator iter = prop_map_.find(key); + if (iter == prop_map_.end()) + return default_value; + return iter->second.value; +} + +void Window::LocalDestroy() { + delete this; +} + +void Window::LocalAddChild(Window* child) { + ScopedTreeNotifier notifier(child, child->parent(), this); + if (child->parent()) + RemoveChildImpl(child, &child->parent_->children_); + children_.push_back(child); + child->parent_ = this; +} + +void Window::LocalRemoveChild(Window* child) { + DCHECK_EQ(this, child->parent()); + ScopedTreeNotifier notifier(child, this, NULL); + RemoveChildImpl(child, &children_); +} + +bool Window::LocalReorder(Window* relative, mojo::OrderDirection direction) { + return ReorderImpl(&parent_->children_, this, relative, direction); +} + +void Window::LocalSetBounds(const mojo::Rect& old_bounds, + const mojo::Rect& new_bounds) { + DCHECK(old_bounds.x == bounds_.x); + DCHECK(old_bounds.y == bounds_.y); + DCHECK(old_bounds.width == bounds_.width); + DCHECK(old_bounds.height == bounds_.height); + ScopedSetBoundsNotifier notifier(this, old_bounds, new_bounds); + bounds_ = new_bounds; +} + +void Window::LocalSetViewportMetrics(const mojo::ViewportMetrics& old_metrics, + const mojo::ViewportMetrics& new_metrics) { + // TODO(eseidel): We could check old_metrics against viewport_metrics_. + viewport_metrics_ = new_metrics.Clone(); + FOR_EACH_OBSERVER( + WindowObserver, observers_, + OnWindowViewportMetricsChanged(this, old_metrics, new_metrics)); +} + +void Window::LocalSetDrawn(bool value) { + if (drawn_ == value) + return; + + // As IsDrawn() is derived from |visible_| and |drawn_|, only send drawn + // notification is the value of IsDrawn() is really changing. + if (IsDrawn() == value) { + drawn_ = value; + return; + } + FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowDrawnChanging(this)); + drawn_ = value; + FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowDrawnChanged(this)); +} + +void Window::LocalSetVisible(bool visible) { + if (visible_ == visible) + return; + + FOR_EACH_OBSERVER(WindowObserver, observers_, + OnWindowVisibilityChanging(this)); + visible_ = visible; + NotifyWindowVisibilityChanged(this); +} + +void Window::NotifyWindowVisibilityChanged(Window* target) { + if (!NotifyWindowVisibilityChangedDown(target)) { + return; // |this| has been deleted. + } + NotifyWindowVisibilityChangedUp(target); +} + +bool Window::NotifyWindowVisibilityChangedAtReceiver(Window* target) { + // |this| may be deleted during a call to OnWindowVisibilityChanged() on one + // of the observers. We create an local observer for that. In that case we + // exit without further access to any members. + WindowTracker tracker; + tracker.Add(this); + FOR_EACH_OBSERVER(WindowObserver, observers_, + OnWindowVisibilityChanged(target)); + return tracker.Contains(this); +} + +bool Window::NotifyWindowVisibilityChangedDown(Window* target) { + if (!NotifyWindowVisibilityChangedAtReceiver(target)) + return false; // |this| was deleted. + std::set<const Window*> child_already_processed; + bool child_destroyed = false; + do { + child_destroyed = false; + for (Window::Children::const_iterator it = children_.begin(); + it != children_.end(); ++it) { + if (!child_already_processed.insert(*it).second) + continue; + if (!(*it)->NotifyWindowVisibilityChangedDown(target)) { + // |*it| was deleted, |it| is invalid and |children_| has changed. We + // exit the current for-loop and enter a new one. + child_destroyed = true; + break; + } + } + } while (child_destroyed); + return true; +} + +void Window::NotifyWindowVisibilityChangedUp(Window* target) { + // Start with the parent as we already notified |this| + // in NotifyWindowVisibilityChangedDown. + for (Window* window = parent(); window; window = window->parent()) { + bool ret = window->NotifyWindowVisibilityChangedAtReceiver(target); + DCHECK(ret); + } +} + +bool Window::PrepareForEmbed() { + if (!OwnsWindow(connection_, this) && + !static_cast<WindowTreeClientImpl*>(connection_)->is_embed_root()) { + return false; + } + + while (!children_.empty()) + RemoveChild(children_[0]); + return true; +} + +} // namespace mus
diff --git a/components/mus/public/cpp/lib/view_observer.cc b/components/mus/public/cpp/lib/window_observer.cc similarity index 74% rename from components/mus/public/cpp/lib/view_observer.cc rename to components/mus/public/cpp/lib/window_observer.cc index 40367ea..26e6507 100644 --- a/components/mus/public/cpp/lib/view_observer.cc +++ b/components/mus/public/cpp/lib/window_observer.cc
@@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/mus/public/cpp/view_observer.h" +#include "components/mus/public/cpp/window_observer.h" namespace mus { //////////////////////////////////////////////////////////////////////////////// -// ViewObserver, public: +// WindowObserver, public: -ViewObserver::TreeChangeParams::TreeChangeParams() +WindowObserver::TreeChangeParams::TreeChangeParams() : target(nullptr), old_parent(nullptr), new_parent(nullptr),
diff --git a/components/mus/public/cpp/lib/window_private.cc b/components/mus/public/cpp/lib/window_private.cc new file mode 100644 index 0000000..5d8dca75 --- /dev/null +++ b/components/mus/public/cpp/lib/window_private.cc
@@ -0,0 +1,20 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/mus/public/cpp/lib/window_private.h" + +namespace mus { + +WindowPrivate::WindowPrivate(Window* window) : window_(window) { + CHECK(window); +} + +WindowPrivate::~WindowPrivate() {} + +// static +Window* WindowPrivate::LocalCreate() { + return new Window; +} + +} // namespace mus
diff --git a/components/mus/public/cpp/lib/window_private.h b/components/mus/public/cpp/lib/window_private.h new file mode 100644 index 0000000..6dd6b80 --- /dev/null +++ b/components/mus/public/cpp/lib/window_private.h
@@ -0,0 +1,68 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_MUS_PUBLIC_CPP_LIB_WINDOW_PRIVATE_H_ +#define COMPONENTS_MUS_PUBLIC_CPP_LIB_WINDOW_PRIVATE_H_ + +#include "components/mus/public/cpp/window.h" + +namespace mus { + +// This class is a friend of a View and contains functions to mutate internal +// state of View. +class WindowPrivate { + public: + explicit WindowPrivate(Window* view); + ~WindowPrivate(); + + // Creates and returns a new View. Caller owns the return value. + static Window* LocalCreate(); + + base::ObserverList<WindowObserver>* observers() { + return &window_->observers_; + } + + void ClearParent() { window_->parent_ = NULL; } + + void set_visible(bool visible) { window_->visible_ = visible; } + + void set_drawn(bool drawn) { window_->drawn_ = drawn; } + + void set_id(Id id) { window_->id_ = id; } + + void set_connection(WindowTreeConnection* connection) { + window_->connection_ = connection; + } + + void set_properties(const std::map<std::string, std::vector<uint8_t>>& data) { + window_->properties_ = data; + } + + void LocalSetViewportMetrics(const mojo::ViewportMetrics& old_metrics, + const mojo::ViewportMetrics& new_metrics) { + window_->LocalSetViewportMetrics(new_metrics, new_metrics); + } + + void LocalDestroy() { window_->LocalDestroy(); } + void LocalAddChild(Window* child) { window_->LocalAddChild(child); } + void LocalRemoveChild(Window* child) { window_->LocalRemoveChild(child); } + void LocalReorder(Window* relative, mojo::OrderDirection direction) { + window_->LocalReorder(relative, direction); + } + void LocalSetBounds(const mojo::Rect& old_bounds, + const mojo::Rect& new_bounds) { + window_->LocalSetBounds(old_bounds, new_bounds); + } + void LocalSetDrawn(bool drawn) { window_->LocalSetDrawn(drawn); } + void LocalSetVisible(bool visible) { window_->LocalSetVisible(visible); } + + private: + Window* window_; + + MOJO_DISALLOW_COPY_AND_ASSIGN(WindowPrivate); +}; + +} // namespace mus + +#endif // COMPONENTS_MUS_PUBLIC_CPP_LIB_WINDOW_PRIVATE_H_
diff --git a/components/mus/public/cpp/lib/view_surface.cc b/components/mus/public/cpp/lib/window_surface.cc similarity index 71% rename from components/mus/public/cpp/lib/view_surface.cc rename to components/mus/public/cpp/lib/window_surface.cc index 47409f7..78c4f55a 100644 --- a/components/mus/public/cpp/lib/view_surface.cc +++ b/components/mus/public/cpp/lib/window_surface.cc
@@ -2,16 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/mus/public/cpp/view_surface.h" +#include "components/mus/public/cpp/window_surface.h" -#include "components/mus/public/cpp/view_surface_client.h" +#include "components/mus/public/cpp/window_surface_client.h" #include "mojo/converters/surfaces/surfaces_type_converters.h" namespace mus { -ViewSurface::~ViewSurface() {} +WindowSurface::~WindowSurface() {} -void ViewSurface::BindToThread() { +void WindowSurface::BindToThread() { DCHECK(!bound_to_thread_); bound_to_thread_ = true; surface_.Bind(surface_info_.Pass()); @@ -19,15 +19,15 @@ new mojo::Binding<mojo::SurfaceClient>(this, client_request_.Pass())); } -void ViewSurface::SubmitCompositorFrame(mojo::CompositorFramePtr frame, - const mojo::Closure& callback) { +void WindowSurface::SubmitCompositorFrame(mojo::CompositorFramePtr frame, + const mojo::Closure& callback) { DCHECK(bound_to_thread_); if (!surface_) return; surface_->SubmitCompositorFrame(frame.Pass(), callback); } -ViewSurface::ViewSurface( +WindowSurface::WindowSurface( mojo::InterfacePtrInfo<mojo::Surface> surface_info, mojo::InterfaceRequest<mojo::SurfaceClient> client_request) : client_(nullptr), @@ -35,7 +35,7 @@ client_request_(client_request.Pass()), bound_to_thread_(false) {} -void ViewSurface::ReturnResources( +void WindowSurface::ReturnResources( mojo::Array<mojo::ReturnedResourcePtr> resources) { if (!client_) return;
diff --git a/components/mus/public/cpp/lib/window_tree_client_impl.cc b/components/mus/public/cpp/lib/window_tree_client_impl.cc new file mode 100644 index 0000000..0fc663e --- /dev/null +++ b/components/mus/public/cpp/lib/window_tree_client_impl.cc
@@ -0,0 +1,457 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/mus/public/cpp/lib/window_tree_client_impl.h" + +#include "components/mus/public/cpp/lib/window_private.h" +#include "components/mus/public/cpp/util.h" +#include "components/mus/public/cpp/window_observer.h" +#include "components/mus/public/cpp/window_tree_connection.h" +#include "components/mus/public/cpp/window_tree_delegate.h" +#include "mojo/application/public/cpp/application_impl.h" +#include "mojo/application/public/cpp/connect.h" +#include "mojo/application/public/cpp/service_provider_impl.h" +#include "mojo/application/public/interfaces/service_provider.mojom.h" + +namespace mus { + +Id MakeTransportId(ConnectionSpecificId connection_id, + ConnectionSpecificId local_id) { + return (connection_id << 16) | local_id; +} + +// Helper called to construct a local window object from transport data. +Window* AddWindowToConnection(WindowTreeClientImpl* client, + Window* parent, + const mojo::ViewDataPtr& window_data) { + // We don't use the cto that takes a WindowTreeConnection here, since it will + // call back to the service and attempt to create a new view. + Window* window = WindowPrivate::LocalCreate(); + WindowPrivate private_window(window); + private_window.set_connection(client); + private_window.set_id(window_data->view_id); + private_window.set_visible(window_data->visible); + private_window.set_drawn(window_data->drawn); + private_window.LocalSetViewportMetrics(mojo::ViewportMetrics(), + *window_data->viewport_metrics); + private_window.set_properties( + window_data->properties + .To<std::map<std::string, std::vector<uint8_t>>>()); + client->AddWindow(window); + private_window.LocalSetBounds(mojo::Rect(), *window_data->bounds); + if (parent) + WindowPrivate(parent).LocalAddChild(window); + return window; +} + +Window* BuildWindowTree(WindowTreeClientImpl* client, + const mojo::Array<mojo::ViewDataPtr>& windows, + Window* initial_parent) { + std::vector<Window*> parents; + Window* root = NULL; + Window* last_window = NULL; + if (initial_parent) + parents.push_back(initial_parent); + for (size_t i = 0; i < windows.size(); ++i) { + if (last_window && windows[i]->parent_id == last_window->id()) { + parents.push_back(last_window); + } else if (!parents.empty()) { + while (parents.back()->id() != windows[i]->parent_id) + parents.pop_back(); + } + Window* window = AddWindowToConnection( + client, !parents.empty() ? parents.back() : NULL, windows[i]); + if (!last_window) + root = window; + last_window = window; + } + return root; +} + +WindowTreeConnection* WindowTreeConnection::Create( + WindowTreeDelegate* delegate, + mojo::InterfaceRequest<mojo::ViewTreeClient> request, + CreateType create_type) { + WindowTreeClientImpl* client = + new WindowTreeClientImpl(delegate, request.Pass()); + if (create_type == CreateType::WAIT_FOR_EMBED) + client->WaitForEmbed(); + return client; +} + +WindowTreeClientImpl::WindowTreeClientImpl( + WindowTreeDelegate* delegate, + mojo::InterfaceRequest<mojo::ViewTreeClient> request) + : connection_id_(0), + next_id_(1), + delegate_(delegate), + root_(nullptr), + capture_window_(nullptr), + focused_window_(nullptr), + activated_window_(nullptr), + binding_(this, request.Pass()), + is_embed_root_(false), + in_destructor_(false) {} + +WindowTreeClientImpl::~WindowTreeClientImpl() { + in_destructor_ = true; + + std::vector<Window*> non_owned; + while (!windows_.empty()) { + IdToWindowMap::iterator it = windows_.begin(); + if (OwnsWindow(it->second->id())) { + it->second->Destroy(); + } else { + non_owned.push_back(it->second); + windows_.erase(it); + } + } + + // Delete the non-owned views last. In the typical case these are roots. The + // exception is the window manager and embed roots, which may know about + // other random windows that it doesn't own. + // NOTE: we manually delete as we're a friend. + for (size_t i = 0; i < non_owned.size(); ++i) + delete non_owned[i]; + + delegate_->OnConnectionLost(this); +} + +void WindowTreeClientImpl::WaitForEmbed() { + DCHECK(!root_); + // OnEmbed() is the first function called. + binding_.WaitForIncomingMethodCall(); + // TODO(sky): deal with pipe being closed before we get OnEmbed(). +} + +void WindowTreeClientImpl::DestroyWindow(Id window_id) { + DCHECK(tree_); + tree_->DeleteView(window_id, ActionCompletedCallback()); +} + +void WindowTreeClientImpl::AddChild(Id child_id, Id parent_id) { + DCHECK(tree_); + tree_->AddView(parent_id, child_id, ActionCompletedCallback()); +} + +void WindowTreeClientImpl::RemoveChild(Id child_id, Id parent_id) { + DCHECK(tree_); + tree_->RemoveViewFromParent(child_id, ActionCompletedCallback()); +} + +void WindowTreeClientImpl::Reorder(Id window_id, + Id relative_window_id, + mojo::OrderDirection direction) { + DCHECK(tree_); + tree_->ReorderView(window_id, relative_window_id, direction, + ActionCompletedCallback()); +} + +bool WindowTreeClientImpl::OwnsWindow(Id id) const { + return HiWord(id) == connection_id_; +} + +void WindowTreeClientImpl::SetBounds(Id window_id, const mojo::Rect& bounds) { + DCHECK(tree_); + tree_->SetViewBounds(window_id, bounds.Clone(), ActionCompletedCallback()); +} + +void WindowTreeClientImpl::SetFocus(Id window_id) { + // In order for us to get here we had to have exposed a window, which implies + // we + // got a connection. + DCHECK(tree_); + tree_->SetFocus(window_id); +} + +void WindowTreeClientImpl::SetVisible(Id window_id, bool visible) { + DCHECK(tree_); + tree_->SetViewVisibility(window_id, visible, ActionCompletedCallback()); +} + +void WindowTreeClientImpl::SetProperty(Id window_id, + const std::string& name, + const std::vector<uint8_t>& data) { + DCHECK(tree_); + tree_->SetViewProperty(window_id, mojo::String(name), + mojo::Array<uint8_t>::From(data), + ActionCompletedCallback()); +} + +void WindowTreeClientImpl::SetViewTextInputState( + Id window_id, + mojo::TextInputStatePtr state) { + DCHECK(tree_); + tree_->SetViewTextInputState(window_id, state.Pass()); +} + +void WindowTreeClientImpl::SetImeVisibility(Id window_id, + bool visible, + mojo::TextInputStatePtr state) { + DCHECK(tree_); + tree_->SetImeVisibility(window_id, visible, state.Pass()); +} + +void WindowTreeClientImpl::Embed( + Id window_id, + mojo::ViewTreeClientPtr client, + uint32_t policy_bitmask, + const mojo::ViewTree::EmbedCallback& callback) { + DCHECK(tree_); + tree_->Embed(window_id, client.Pass(), policy_bitmask, callback); +} + +void WindowTreeClientImpl::RequestSurface( + Id window_id, + mojo::InterfaceRequest<mojo::Surface> surface, + mojo::SurfaceClientPtr client) { + DCHECK(tree_); + tree_->RequestSurface(window_id, surface.Pass(), client.Pass()); +} + +void WindowTreeClientImpl::AddWindow(Window* window) { + DCHECK(windows_.find(window->id()) == windows_.end()); + windows_[window->id()] = window; +} + +void WindowTreeClientImpl::RemoveWindow(Id window_id) { + if (focused_window_ && focused_window_->id() == window_id) + OnWindowFocused(0); + + IdToWindowMap::iterator it = windows_.find(window_id); + if (it != windows_.end()) + windows_.erase(it); +} + +void WindowTreeClientImpl::OnRootDestroyed(Window* root) { + DCHECK_EQ(root, root_); + root_ = nullptr; + + // When the root is gone we can't do anything useful. + if (!in_destructor_) + delete this; +} + +//////////////////////////////////////////////////////////////////////////////// +// WindowTreeClientImpl, WindowTreeConnection implementation: + +Id WindowTreeClientImpl::CreateWindowOnServer() { + DCHECK(tree_); + const Id window_id = MakeTransportId(connection_id_, next_id_++); + tree_->CreateView(window_id, [this](mojo::ErrorCode code) { + OnActionCompleted(code == mojo::ERROR_CODE_NONE); + }); + return window_id; +} + +Window* WindowTreeClientImpl::GetRoot() { + return root_; +} + +Window* WindowTreeClientImpl::GetWindowById(Id id) { + IdToWindowMap::const_iterator it = windows_.find(id); + return it != windows_.end() ? it->second : NULL; +} + +Window* WindowTreeClientImpl::GetFocusedWindow() { + return focused_window_; +} + +Window* WindowTreeClientImpl::CreateWindow() { + Window* window = new Window(this, CreateWindowOnServer()); + AddWindow(window); + return window; +} + +bool WindowTreeClientImpl::IsEmbedRoot() { + return is_embed_root_; +} + +ConnectionSpecificId WindowTreeClientImpl::GetConnectionId() { + return connection_id_; +} + +//////////////////////////////////////////////////////////////////////////////// +// WindowTreeClientImpl, ViewTreeClient implementation: + +void WindowTreeClientImpl::OnEmbed(ConnectionSpecificId connection_id, + mojo::ViewDataPtr root_data, + mojo::ViewTreePtr tree, + Id focused_window_id, + uint32 access_policy) { + if (tree) { + DCHECK(!tree_); + tree_ = tree.Pass(); + tree_.set_connection_error_handler([this]() { delete this; }); + } + connection_id_ = connection_id; + is_embed_root_ = + (access_policy & mojo::ViewTree::ACCESS_POLICY_EMBED_ROOT) != 0; + + DCHECK(!root_); + root_ = AddWindowToConnection(this, nullptr, root_data); + + focused_window_ = GetWindowById(focused_window_id); + + delegate_->OnEmbed(root_); +} + +void WindowTreeClientImpl::OnEmbeddedAppDisconnected(Id window_id) { + Window* window = GetWindowById(window_id); + if (window) { + FOR_EACH_OBSERVER(WindowObserver, *WindowPrivate(window).observers(), + OnWindowEmbeddedAppDisconnected(window)); + } +} + +void WindowTreeClientImpl::OnUnembed() { + delegate_->OnUnembed(); + // This will send out the various notifications. + delete this; +} + +void WindowTreeClientImpl::OnWindowBoundsChanged(Id window_id, + mojo::RectPtr old_bounds, + mojo::RectPtr new_bounds) { + Window* window = GetWindowById(window_id); + WindowPrivate(window).LocalSetBounds(*old_bounds, *new_bounds); +} + +namespace { + +void SetViewportMetricsOnDecendants(Window* root, + const mojo::ViewportMetrics& old_metrics, + const mojo::ViewportMetrics& new_metrics) { + WindowPrivate(root).LocalSetViewportMetrics(old_metrics, new_metrics); + const Window::Children& children = root->children(); + for (size_t i = 0; i < children.size(); ++i) + SetViewportMetricsOnDecendants(children[i], old_metrics, new_metrics); +} +} + +void WindowTreeClientImpl::OnWindowViewportMetricsChanged( + mojo::ViewportMetricsPtr old_metrics, + mojo::ViewportMetricsPtr new_metrics) { + Window* window = GetRoot(); + if (window) + SetViewportMetricsOnDecendants(window, *old_metrics, *new_metrics); +} + +void WindowTreeClientImpl::OnWindowHierarchyChanged( + Id window_id, + Id new_parent_id, + Id old_parent_id, + mojo::Array<mojo::ViewDataPtr> windows) { + Window* initial_parent = + windows.size() ? GetWindowById(windows[0]->parent_id) : NULL; + + const bool was_window_known = GetWindowById(window_id) != nullptr; + + BuildWindowTree(this, windows, initial_parent); + + // If the window was not known, then BuildWindowTree() will have created it + // and + // parented the window. + if (!was_window_known) + return; + + Window* new_parent = GetWindowById(new_parent_id); + Window* old_parent = GetWindowById(old_parent_id); + Window* window = GetWindowById(window_id); + if (new_parent) + WindowPrivate(new_parent).LocalAddChild(window); + else + WindowPrivate(old_parent).LocalRemoveChild(window); +} + +void WindowTreeClientImpl::OnWindowReordered(Id window_id, + Id relative_window_id, + mojo::OrderDirection direction) { + Window* window = GetWindowById(window_id); + Window* relative_window = GetWindowById(relative_window_id); + if (window && relative_window) + WindowPrivate(window).LocalReorder(relative_window, direction); +} + +void WindowTreeClientImpl::OnWindowDeleted(Id window_id) { + Window* window = GetWindowById(window_id); + if (window) + WindowPrivate(window).LocalDestroy(); +} + +void WindowTreeClientImpl::OnWindowVisibilityChanged(Id window_id, + bool visible) { + // TODO(sky): there is a race condition here. If this client and another + // client change the visibility at the same time the wrong value may be set. + // Deal with this some how. + Window* window = GetWindowById(window_id); + if (window) + WindowPrivate(window).LocalSetVisible(visible); +} + +void WindowTreeClientImpl::OnWindowDrawnStateChanged(Id window_id, bool drawn) { + Window* window = GetWindowById(window_id); + if (window) + WindowPrivate(window).LocalSetDrawn(drawn); +} + +void WindowTreeClientImpl::OnWindowSharedPropertyChanged( + Id window_id, + const mojo::String& name, + mojo::Array<uint8_t> new_data) { + Window* window = GetWindowById(window_id); + if (window) { + std::vector<uint8_t> data; + std::vector<uint8_t>* data_ptr = NULL; + if (!new_data.is_null()) { + data = new_data.To<std::vector<uint8_t>>(); + data_ptr = &data; + } + + window->SetSharedProperty(name, data_ptr); + } +} + +void WindowTreeClientImpl::OnWindowInputEvent( + Id window_id, + mojo::EventPtr event, + const mojo::Callback<void()>& ack_callback) { + Window* window = GetWindowById(window_id); + if (window) { + FOR_EACH_OBSERVER(WindowObserver, *WindowPrivate(window).observers(), + OnWindowInputEvent(window, event)); + } + ack_callback.Run(); +} + +void WindowTreeClientImpl::OnWindowFocused(Id focused_window_id) { + Window* focused = GetWindowById(focused_window_id); + Window* blurred = focused_window_; + // Update |focused_window_| before calling any of the observers, so that the + // observers get the correct result from calling |Window::HasFocus()|, + // |WindowTreeConnection::GetFocusedWindow()| etc. + focused_window_ = focused; + if (blurred) { + FOR_EACH_OBSERVER(WindowObserver, *WindowPrivate(blurred).observers(), + OnWindowFocusChanged(focused, blurred)); + } + if (focused) { + FOR_EACH_OBSERVER(WindowObserver, *WindowPrivate(focused).observers(), + OnWindowFocusChanged(focused, blurred)); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// WindowTreeClientImpl, private: + +void WindowTreeClientImpl::OnActionCompleted(bool success) { + if (!change_acked_callback_.is_null()) + change_acked_callback_.Run(); +} + +mojo::Callback<void(bool)> WindowTreeClientImpl::ActionCompletedCallback() { + return [this](bool success) { OnActionCompleted(success); }; +} + +} // namespace mus
diff --git a/components/mus/public/cpp/lib/window_tree_client_impl.h b/components/mus/public/cpp/lib/window_tree_client_impl.h new file mode 100644 index 0000000..7f3a7ba --- /dev/null +++ b/components/mus/public/cpp/lib/window_tree_client_impl.h
@@ -0,0 +1,166 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_MUS_PUBLIC_CPP_LIB_WINDOW_TREE_CLIENT_IMPL_H_ +#define COMPONENTS_MUS_PUBLIC_CPP_LIB_WINDOW_TREE_CLIENT_IMPL_H_ + +#include "components/mus/public/cpp/types.h" +#include "components/mus/public/cpp/window.h" +#include "components/mus/public/cpp/window_tree_connection.h" +#include "components/mus/public/interfaces/view_tree.mojom.h" +#include "third_party/mojo/src/mojo/public/cpp/bindings/strong_binding.h" + +namespace mus { +class WindowTreeConnection; +class WindowTreeDelegate; + +// Manages the connection with the Window Server service. +class WindowTreeClientImpl : public WindowTreeConnection, + public mojo::ViewTreeClient { + public: + WindowTreeClientImpl(WindowTreeDelegate* delegate, + mojo::InterfaceRequest<mojo::ViewTreeClient> request); + ~WindowTreeClientImpl() override; + + // Wait for OnEmbed(), returning when done. + void WaitForEmbed(); + + bool connected() const { return tree_; } + ConnectionSpecificId connection_id() const { return connection_id_; } + + // API exposed to the window implementations that pushes local changes to the + // service. + void DestroyWindow(Id window_id); + + // These methods take TransportIds. For windows owned by the current + // connection, + // the connection id high word can be zero. In all cases, the TransportId 0x1 + // refers to the root window. + void AddChild(Id child_id, Id parent_id); + void RemoveChild(Id child_id, Id parent_id); + + void Reorder(Id window_id, + Id relative_window_id, + mojo::OrderDirection direction); + + // Returns true if the specified window was created by this connection. + bool OwnsWindow(Id id) const; + + void SetBounds(Id window_id, const mojo::Rect& bounds); + void SetFocus(Id window_id); + void SetVisible(Id window_id, bool visible); + void SetProperty(Id window_id, + const std::string& name, + const std::vector<uint8_t>& data); + void SetViewTextInputState(Id window_id, mojo::TextInputStatePtr state); + void SetImeVisibility(Id window_id, + bool visible, + mojo::TextInputStatePtr state); + + void Embed(Id window_id, + mojo::ViewTreeClientPtr client, + uint32_t policy_bitmask, + const mojo::ViewTree::EmbedCallback& callback); + + void RequestSurface(Id window_id, + mojo::InterfaceRequest<mojo::Surface> surface, + mojo::SurfaceClientPtr client); + + void set_change_acked_callback(const mojo::Callback<void(void)>& callback) { + change_acked_callback_ = callback; + } + void ClearChangeAckedCallback() { change_acked_callback_.reset(); } + + // Start/stop tracking views. While tracked, they can be retrieved via + // WindowTreeConnection::GetWindowById. + void AddWindow(Window* window); + void RemoveWindow(Id window_id); + + bool is_embed_root() const { return is_embed_root_; } + + // Called after the root window's observers have been notified of destruction + // (as the last step of ~Window). This ordering ensures that the Window Server + // is torn down after the root. + void OnRootDestroyed(Window* root); + + private: + typedef std::map<Id, Window*> IdToWindowMap; + + Id CreateWindowOnServer(); + + // Overridden from WindowTreeConnection: + Window* GetRoot() override; + Window* GetWindowById(Id id) override; + Window* GetFocusedWindow() override; + Window* CreateWindow() override; + bool IsEmbedRoot() override; + ConnectionSpecificId GetConnectionId() override; + + // Overridden from ViewTreeClient: + void OnEmbed(ConnectionSpecificId connection_id, + mojo::ViewDataPtr root, + mojo::ViewTreePtr tree, + Id focused_window_id, + uint32_t access_policy) override; + void OnEmbeddedAppDisconnected(Id window_id) override; + void OnUnembed() override; + void OnWindowBoundsChanged(Id window_id, + mojo::RectPtr old_bounds, + mojo::RectPtr new_bounds) override; + void OnWindowViewportMetricsChanged( + mojo::ViewportMetricsPtr old_metrics, + mojo::ViewportMetricsPtr new_metrics) override; + void OnWindowHierarchyChanged( + Id window_id, + Id new_parent_id, + Id old_parent_id, + mojo::Array<mojo::ViewDataPtr> windows) override; + void OnWindowReordered(Id window_id, + Id relative_window_id, + mojo::OrderDirection direction) override; + void OnWindowDeleted(Id window_id) override; + void OnWindowVisibilityChanged(Id window_id, bool visible) override; + void OnWindowDrawnStateChanged(Id window_id, bool drawn) override; + void OnWindowSharedPropertyChanged(Id window_id, + const mojo::String& name, + mojo::Array<uint8_t> new_data) override; + void OnWindowInputEvent(Id window_id, + mojo::EventPtr event, + const mojo::Callback<void()>& callback) override; + void OnWindowFocused(Id focused_window_id) override; + + void RootDestroyed(Window* root); + + void OnActionCompleted(bool success); + + mojo::Callback<void(bool)> ActionCompletedCallback(); + + ConnectionSpecificId connection_id_; + ConnectionSpecificId next_id_; + + mojo::Callback<void(void)> change_acked_callback_; + + WindowTreeDelegate* delegate_; + + Window* root_; + + IdToWindowMap windows_; + + Window* capture_window_; + Window* focused_window_; + Window* activated_window_; + + mojo::Binding<ViewTreeClient> binding_; + mojo::ViewTreePtr tree_; + + bool is_embed_root_; + + bool in_destructor_; + + MOJO_DISALLOW_COPY_AND_ASSIGN(WindowTreeClientImpl); +}; + +} // namespace mus + +#endif // COMPONENTS_MUS_PUBLIC_CPP_LIB_WINDOW_TREE_CLIENT_IMPL_H_
diff --git a/components/mus/public/cpp/lib/view_tree_delegate.cc b/components/mus/public/cpp/lib/window_tree_delegate.cc similarity index 67% rename from components/mus/public/cpp/lib/view_tree_delegate.cc rename to components/mus/public/cpp/lib/window_tree_delegate.cc index c1344146..c9377ba 100644 --- a/components/mus/public/cpp/lib/view_tree_delegate.cc +++ b/components/mus/public/cpp/lib/window_tree_delegate.cc
@@ -2,10 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/mus/public/cpp/view_tree_delegate.h" +#include "components/mus/public/cpp/window_tree_delegate.h" namespace mus { -void ViewTreeDelegate::OnUnembed() {} +void WindowTreeDelegate::OnUnembed() {} } // namespace mus
diff --git a/components/mus/public/cpp/lib/window_tree_host_factory.cc b/components/mus/public/cpp/lib/window_tree_host_factory.cc new file mode 100644 index 0000000..0636559 --- /dev/null +++ b/components/mus/public/cpp/lib/window_tree_host_factory.cc
@@ -0,0 +1,36 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/mus/public/cpp/window_tree_host_factory.h" + +#include "components/mus/public/cpp/window_tree_connection.h" +#include "components/mus/public/cpp/window_tree_delegate.h" +#include "mojo/application/public/cpp/application_impl.h" + +namespace mus { + +void CreateWindowTreeHost(mojo::ViewTreeHostFactory* factory, + mojo::ViewTreeHostClientPtr host_client, + WindowTreeDelegate* delegate, + mojo::ViewTreeHostPtr* host) { + mojo::ViewTreeClientPtr tree_client; + WindowTreeConnection::Create( + delegate, GetProxy(&tree_client), + WindowTreeConnection::CreateType::DONT_WAIT_FOR_EMBED); + factory->CreateWindowTreeHost(GetProxy(host), host_client.Pass(), + tree_client.Pass()); +} + +void CreateSingleWindowTreeHost(mojo::ApplicationImpl* app, + WindowTreeDelegate* delegate, + mojo::ViewTreeHostPtr* host) { + mojo::ViewTreeHostFactoryPtr factory; + mojo::URLRequestPtr request(mojo::URLRequest::New()); + request->url = "mojo:mus"; + app->ConnectToService(request.Pass(), &factory); + CreateWindowTreeHost(factory.get(), mojo::ViewTreeHostClientPtr(), delegate, + host); +} + +} // namespace mus
diff --git a/components/mus/public/cpp/output_surface.h b/components/mus/public/cpp/output_surface.h index e187fb3b..f99665d 100644 --- a/components/mus/public/cpp/output_surface.h +++ b/components/mus/public/cpp/output_surface.h
@@ -8,16 +8,16 @@ #include "base/macros.h" #include "cc/output/output_surface.h" #include "cc/surfaces/surface_id.h" -#include "components/mus/public/cpp/view_surface.h" -#include "components/mus/public/cpp/view_surface_client.h" +#include "components/mus/public/cpp/window_surface.h" +#include "components/mus/public/cpp/window_surface_client.h" #include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h" namespace mus { -class OutputSurface : public cc::OutputSurface, public ViewSurfaceClient { +class OutputSurface : public cc::OutputSurface, public WindowSurfaceClient { public: OutputSurface(const scoped_refptr<cc::ContextProvider>& context_provider, - scoped_ptr<ViewSurface> surface); + scoped_ptr<WindowSurface> surface); ~OutputSurface() override; // cc::OutputSurface implementation. @@ -26,14 +26,14 @@ void DetachFromClient() override; private: - // ViewSurfaceClient implementation: + // WindowSurfaceClient implementation: void OnResourcesReturned( - ViewSurface* surface, + WindowSurface* surface, mojo::Array<mojo::ReturnedResourcePtr> resources) override; void SwapBuffersComplete(); - scoped_ptr<ViewSurface> surface_; + scoped_ptr<WindowSurface> surface_; DISALLOW_COPY_AND_ASSIGN(OutputSurface); };
diff --git a/components/mus/public/cpp/scoped_view_ptr.h b/components/mus/public/cpp/scoped_view_ptr.h deleted file mode 100644 index 92c12f2..0000000 --- a/components/mus/public/cpp/scoped_view_ptr.h +++ /dev/null
@@ -1,38 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_MUS_PUBLIC_CPP_SCOPED_VIEW_PTR_H_ -#define COMPONENTS_MUS_PUBLIC_CPP_SCOPED_VIEW_PTR_H_ - -#include "components/mus/public/cpp/view_observer.h" - -namespace mus { - -// Wraps a View, taking overship of the View. Also deals with View being -// destroyed while ScopedViewPtr still exists. -class ScopedViewPtr : public ViewObserver { - public: - explicit ScopedViewPtr(View* view); - ~ScopedViewPtr() override; - - // Destroys |view|. If |view| is the root of the ViewManager than the - // ViewManager is destroyed (which in turn destroys |view|). - static void DeleteViewOrViewManager(View* view); - - View* view() { return view_; } - const View* view() const { return view_; } - - private: - void DetachFromView(); - - void OnViewDestroying(View* view) override; - - View* view_; - - DISALLOW_COPY_AND_ASSIGN(ScopedViewPtr); -}; - -} // namespace mus - -#endif // COMPONENTS_MUS_PUBLIC_CPP_SCOPED_VIEW_PTR_H_
diff --git a/components/mus/public/cpp/scoped_window_ptr.h b/components/mus/public/cpp/scoped_window_ptr.h new file mode 100644 index 0000000..9fb7ada --- /dev/null +++ b/components/mus/public/cpp/scoped_window_ptr.h
@@ -0,0 +1,38 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_MUS_PUBLIC_CPP_SCOPED_WINDOW_PTR_H_ +#define COMPONENTS_MUS_PUBLIC_CPP_SCOPED_WINDOW_PTR_H_ + +#include "components/mus/public/cpp/window_observer.h" + +namespace mus { + +// Wraps a View, taking overship of the View. Also deals with View being +// destroyed while ScopedWindowPtr still exists. +class ScopedWindowPtr : public WindowObserver { + public: + explicit ScopedWindowPtr(Window* view); + ~ScopedWindowPtr() override; + + // Destroys |window|. If |window| is the root of the WindowManager than the + // WindowManager is destroyed (which in turn destroys |window|). + static void DeleteWindowOrWindowManager(Window* window); + + Window* window() { return window_; } + const Window* window() const { return window_; } + + private: + void DetachFromWindow(); + + void OnWindowDestroying(Window* window) override; + + Window* window_; + + DISALLOW_COPY_AND_ASSIGN(ScopedWindowPtr); +}; + +} // namespace mus + +#endif // COMPONENTS_MUS_PUBLIC_CPP_SCOPED_WINDOW_PTR_H_
diff --git a/components/mus/public/cpp/tests/BUILD.gn b/components/mus/public/cpp/tests/BUILD.gn index c5829949..b9ba5d0 100644 --- a/components/mus/public/cpp/tests/BUILD.gn +++ b/components/mus/public/cpp/tests/BUILD.gn
@@ -9,8 +9,8 @@ testonly = true sources = [ - "view_manager_test_base.cc", - "view_manager_test_base.h", + "window_server_test_base.cc", + "window_server_test_base.h", ] deps = [ @@ -26,9 +26,9 @@ test("mojo_view_manager_lib_unittests") { sources = [ "run_all_unittests.cc", - "view_manager_test_suite.cc", - "view_manager_test_suite.h", - "view_unittest.cc", + "window_server_test_suite.cc", + "window_server_test_suite.h", + "window_unittest.cc", ] deps = [
diff --git a/components/mus/public/cpp/tests/run_all_unittests.cc b/components/mus/public/cpp/tests/run_all_unittests.cc index ee82a07..1af6dbd2 100644 --- a/components/mus/public/cpp/tests/run_all_unittests.cc +++ b/components/mus/public/cpp/tests/run_all_unittests.cc
@@ -4,12 +4,12 @@ #include "base/bind.h" #include "base/test/launcher/unit_test_launcher.h" -#include "components/mus/public/cpp/tests/view_manager_test_suite.h" +#include "components/mus/public/cpp/tests/window_server_test_suite.h" int main(int argc, char** argv) { - mus::ViewManagerTestSuite test_suite(argc, argv); + mus::WindowServerTestSuite test_suite(argc, argv); return base::LaunchUnitTests(argc, argv, - base::Bind(&mus::ViewManagerTestSuite::Run, + base::Bind(&mus::WindowServerTestSuite::Run, base::Unretained(&test_suite))); }
diff --git a/components/mus/public/cpp/tests/view_manager_test_suite.h b/components/mus/public/cpp/tests/view_manager_test_suite.h deleted file mode 100644 index b68bb2f3..0000000 --- a/components/mus/public/cpp/tests/view_manager_test_suite.h +++ /dev/null
@@ -1,27 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_MUS_PUBLIC_CPP_TESTS_VIEW_MANAGER_TEST_SUITE_H_ -#define COMPONENTS_MUS_PUBLIC_CPP_TESTS_VIEW_MANAGER_TEST_SUITE_H_ - -#include "base/test/test_suite.h" -#include "third_party/mojo/src/mojo/public/cpp/system/macros.h" - -namespace mus { - -class ViewManagerTestSuite : public base::TestSuite { - public: - ViewManagerTestSuite(int argc, char** argv); - ~ViewManagerTestSuite() override; - - protected: - void Initialize() override; - - private: - MOJO_DISALLOW_COPY_AND_ASSIGN(ViewManagerTestSuite); -}; - -} // namespace mus - -#endif // COMPONENTS_MUS_PUBLIC_CPP_TESTS_VIEW_MANAGER_TEST_SUITE_H_
diff --git a/components/mus/public/cpp/tests/view_unittest.cc b/components/mus/public/cpp/tests/view_unittest.cc deleted file mode 100644 index c991ca3..0000000 --- a/components/mus/public/cpp/tests/view_unittest.cc +++ /dev/null
@@ -1,874 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/mus/public/cpp/view.h" - -#include "base/logging.h" -#include "base/strings/stringprintf.h" -#include "components/mus/public/cpp/lib/view_private.h" -#include "components/mus/public/cpp/util.h" -#include "components/mus/public/cpp/view_observer.h" -#include "components/mus/public/cpp/view_property.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mus { - -// View ------------------------------------------------------------------------ - -typedef testing::Test ViewTest; - -// Subclass with public ctor/dtor. -class TestView : public View { - public: - TestView() { ViewPrivate(this).set_id(1); } - ~TestView() {} - - private: - MOJO_DISALLOW_COPY_AND_ASSIGN(TestView); -}; - -TEST_F(ViewTest, AddChild) { - TestView v1; - TestView v11; - v1.AddChild(&v11); - EXPECT_EQ(1U, v1.children().size()); -} - -TEST_F(ViewTest, RemoveChild) { - TestView v1; - TestView v11; - v1.AddChild(&v11); - EXPECT_EQ(1U, v1.children().size()); - v1.RemoveChild(&v11); - EXPECT_EQ(0U, v1.children().size()); -} - -TEST_F(ViewTest, Reparent) { - TestView v1; - TestView v2; - TestView v11; - v1.AddChild(&v11); - EXPECT_EQ(1U, v1.children().size()); - v2.AddChild(&v11); - EXPECT_EQ(1U, v2.children().size()); - EXPECT_EQ(0U, v1.children().size()); -} - -TEST_F(ViewTest, Contains) { - TestView v1; - - // Direct descendant. - TestView v11; - v1.AddChild(&v11); - EXPECT_TRUE(v1.Contains(&v11)); - - // Indirect descendant. - TestView v111; - v11.AddChild(&v111); - EXPECT_TRUE(v1.Contains(&v111)); -} - -TEST_F(ViewTest, GetChildById) { - TestView v1; - ViewPrivate(&v1).set_id(1); - TestView v11; - ViewPrivate(&v11).set_id(11); - v1.AddChild(&v11); - TestView v111; - ViewPrivate(&v111).set_id(111); - v11.AddChild(&v111); - - // Find direct & indirect descendents. - EXPECT_EQ(&v11, v1.GetChildById(v11.id())); - EXPECT_EQ(&v111, v1.GetChildById(v111.id())); -} - -TEST_F(ViewTest, DrawnAndVisible) { - TestView v1; - EXPECT_TRUE(v1.visible()); - EXPECT_FALSE(v1.IsDrawn()); - - ViewPrivate(&v1).set_drawn(true); - - TestView v11; - v1.AddChild(&v11); - EXPECT_TRUE(v11.visible()); - EXPECT_TRUE(v11.IsDrawn()); - - v1.RemoveChild(&v11); - EXPECT_TRUE(v11.visible()); - EXPECT_FALSE(v11.IsDrawn()); -} - -namespace { -DEFINE_VIEW_PROPERTY_KEY(int, kIntKey, -2); -DEFINE_VIEW_PROPERTY_KEY(const char*, kStringKey, "squeamish"); -} - -TEST_F(ViewTest, Property) { - TestView v; - - // Non-existent properties should return the default values. - EXPECT_EQ(-2, v.GetLocalProperty(kIntKey)); - EXPECT_EQ(std::string("squeamish"), v.GetLocalProperty(kStringKey)); - - // A set property value should be returned again (even if it's the default - // value). - v.SetLocalProperty(kIntKey, INT_MAX); - EXPECT_EQ(INT_MAX, v.GetLocalProperty(kIntKey)); - v.SetLocalProperty(kIntKey, -2); - EXPECT_EQ(-2, v.GetLocalProperty(kIntKey)); - v.SetLocalProperty(kIntKey, INT_MIN); - EXPECT_EQ(INT_MIN, v.GetLocalProperty(kIntKey)); - - v.SetLocalProperty(kStringKey, static_cast<const char*>(NULL)); - EXPECT_EQ(NULL, v.GetLocalProperty(kStringKey)); - v.SetLocalProperty(kStringKey, "squeamish"); - EXPECT_EQ(std::string("squeamish"), v.GetLocalProperty(kStringKey)); - v.SetLocalProperty(kStringKey, "ossifrage"); - EXPECT_EQ(std::string("ossifrage"), v.GetLocalProperty(kStringKey)); - - // ClearProperty should restore the default value. - v.ClearLocalProperty(kIntKey); - EXPECT_EQ(-2, v.GetLocalProperty(kIntKey)); - v.ClearLocalProperty(kStringKey); - EXPECT_EQ(std::string("squeamish"), v.GetLocalProperty(kStringKey)); -} - -namespace { - -class TestProperty { - public: - TestProperty() {} - virtual ~TestProperty() { last_deleted_ = this; } - static TestProperty* last_deleted() { return last_deleted_; } - - private: - static TestProperty* last_deleted_; - MOJO_DISALLOW_COPY_AND_ASSIGN(TestProperty); -}; - -TestProperty* TestProperty::last_deleted_ = NULL; - -DEFINE_OWNED_VIEW_PROPERTY_KEY(TestProperty, kOwnedKey, NULL); - -} // namespace - -TEST_F(ViewTest, OwnedProperty) { - TestProperty* p3 = NULL; - { - TestView v; - EXPECT_EQ(NULL, v.GetLocalProperty(kOwnedKey)); - TestProperty* p1 = new TestProperty(); - v.SetLocalProperty(kOwnedKey, p1); - EXPECT_EQ(p1, v.GetLocalProperty(kOwnedKey)); - EXPECT_EQ(NULL, TestProperty::last_deleted()); - - TestProperty* p2 = new TestProperty(); - v.SetLocalProperty(kOwnedKey, p2); - EXPECT_EQ(p2, v.GetLocalProperty(kOwnedKey)); - EXPECT_EQ(p1, TestProperty::last_deleted()); - - v.ClearLocalProperty(kOwnedKey); - EXPECT_EQ(NULL, v.GetLocalProperty(kOwnedKey)); - EXPECT_EQ(p2, TestProperty::last_deleted()); - - p3 = new TestProperty(); - v.SetLocalProperty(kOwnedKey, p3); - EXPECT_EQ(p3, v.GetLocalProperty(kOwnedKey)); - EXPECT_EQ(p2, TestProperty::last_deleted()); - } - - EXPECT_EQ(p3, TestProperty::last_deleted()); -} - -// ViewObserver -------------------------------------------------------- - -typedef testing::Test ViewObserverTest; - -bool TreeChangeParamsMatch(const ViewObserver::TreeChangeParams& lhs, - const ViewObserver::TreeChangeParams& rhs) { - return lhs.target == rhs.target && lhs.old_parent == rhs.old_parent && - lhs.new_parent == rhs.new_parent && lhs.receiver == rhs.receiver; -} - -class TreeChangeObserver : public ViewObserver { - public: - explicit TreeChangeObserver(View* observee) : observee_(observee) { - observee_->AddObserver(this); - } - ~TreeChangeObserver() override { observee_->RemoveObserver(this); } - - void Reset() { received_params_.clear(); } - - const std::vector<TreeChangeParams>& received_params() { - return received_params_; - } - - private: - // Overridden from ViewObserver: - void OnTreeChanging(const TreeChangeParams& params) override { - received_params_.push_back(params); - } - void OnTreeChanged(const TreeChangeParams& params) override { - received_params_.push_back(params); - } - - View* observee_; - std::vector<TreeChangeParams> received_params_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(TreeChangeObserver); -}; - -// Adds/Removes v11 to v1. -TEST_F(ViewObserverTest, TreeChange_SimpleAddRemove) { - TestView v1; - TreeChangeObserver o1(&v1); - EXPECT_TRUE(o1.received_params().empty()); - - TestView v11; - TreeChangeObserver o11(&v11); - EXPECT_TRUE(o11.received_params().empty()); - - // Add. - - v1.AddChild(&v11); - - EXPECT_EQ(2U, o1.received_params().size()); - ViewObserver::TreeChangeParams p1; - p1.target = &v11; - p1.receiver = &v1; - p1.old_parent = NULL; - p1.new_parent = &v1; - EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().back())); - - EXPECT_EQ(2U, o11.received_params().size()); - ViewObserver::TreeChangeParams p11 = p1; - p11.receiver = &v11; - EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().front())); - EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().back())); - - o1.Reset(); - o11.Reset(); - EXPECT_TRUE(o1.received_params().empty()); - EXPECT_TRUE(o11.received_params().empty()); - - // Remove. - - v1.RemoveChild(&v11); - - EXPECT_EQ(2U, o1.received_params().size()); - p1.target = &v11; - p1.receiver = &v1; - p1.old_parent = &v1; - p1.new_parent = NULL; - EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().front())); - - EXPECT_EQ(2U, o11.received_params().size()); - p11 = p1; - p11.receiver = &v11; - EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().front())); - EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().back())); -} - -// Creates these two trees: -// v1 -// +- v11 -// v111 -// +- v1111 -// +- v1112 -// Then adds/removes v111 from v11. -TEST_F(ViewObserverTest, TreeChange_NestedAddRemove) { - TestView v1, v11, v111, v1111, v1112; - - // Root tree. - v1.AddChild(&v11); - - // Tree to be attached. - v111.AddChild(&v1111); - v111.AddChild(&v1112); - - TreeChangeObserver o1(&v1), o11(&v11), o111(&v111), o1111(&v1111), - o1112(&v1112); - ViewObserver::TreeChangeParams p1, p11, p111, p1111, p1112; - - // Add. - - v11.AddChild(&v111); - - EXPECT_EQ(2U, o1.received_params().size()); - p1.target = &v111; - p1.receiver = &v1; - p1.old_parent = NULL; - p1.new_parent = &v11; - EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().back())); - - EXPECT_EQ(2U, o11.received_params().size()); - p11 = p1; - p11.receiver = &v11; - EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().back())); - - EXPECT_EQ(2U, o111.received_params().size()); - p111 = p11; - p111.receiver = &v111; - EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().front())); - EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().back())); - - EXPECT_EQ(2U, o1111.received_params().size()); - p1111 = p111; - p1111.receiver = &v1111; - EXPECT_TRUE(TreeChangeParamsMatch(p1111, o1111.received_params().front())); - EXPECT_TRUE(TreeChangeParamsMatch(p1111, o1111.received_params().back())); - - EXPECT_EQ(2U, o1112.received_params().size()); - p1112 = p111; - p1112.receiver = &v1112; - EXPECT_TRUE(TreeChangeParamsMatch(p1112, o1112.received_params().front())); - EXPECT_TRUE(TreeChangeParamsMatch(p1112, o1112.received_params().back())); - - // Remove. - o1.Reset(); - o11.Reset(); - o111.Reset(); - o1111.Reset(); - o1112.Reset(); - EXPECT_TRUE(o1.received_params().empty()); - EXPECT_TRUE(o11.received_params().empty()); - EXPECT_TRUE(o111.received_params().empty()); - EXPECT_TRUE(o1111.received_params().empty()); - EXPECT_TRUE(o1112.received_params().empty()); - - v11.RemoveChild(&v111); - - EXPECT_EQ(2U, o1.received_params().size()); - p1.target = &v111; - p1.receiver = &v1; - p1.old_parent = &v11; - p1.new_parent = NULL; - EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().front())); - - EXPECT_EQ(2U, o11.received_params().size()); - p11 = p1; - p11.receiver = &v11; - EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().front())); - - EXPECT_EQ(2U, o111.received_params().size()); - p111 = p11; - p111.receiver = &v111; - EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().front())); - EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().back())); - - EXPECT_EQ(2U, o1111.received_params().size()); - p1111 = p111; - p1111.receiver = &v1111; - EXPECT_TRUE(TreeChangeParamsMatch(p1111, o1111.received_params().front())); - EXPECT_TRUE(TreeChangeParamsMatch(p1111, o1111.received_params().back())); - - EXPECT_EQ(2U, o1112.received_params().size()); - p1112 = p111; - p1112.receiver = &v1112; - EXPECT_TRUE(TreeChangeParamsMatch(p1112, o1112.received_params().front())); - EXPECT_TRUE(TreeChangeParamsMatch(p1112, o1112.received_params().back())); -} - -TEST_F(ViewObserverTest, TreeChange_Reparent) { - TestView v1, v11, v12, v111; - v1.AddChild(&v11); - v1.AddChild(&v12); - v11.AddChild(&v111); - - TreeChangeObserver o1(&v1), o11(&v11), o12(&v12), o111(&v111); - - // Reparent. - v12.AddChild(&v111); - - // v1 (root) should see both changing and changed notifications. - EXPECT_EQ(4U, o1.received_params().size()); - ViewObserver::TreeChangeParams p1; - p1.target = &v111; - p1.receiver = &v1; - p1.old_parent = &v11; - p1.new_parent = &v12; - EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().front())); - EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().back())); - - // v11 should see changing notifications. - EXPECT_EQ(2U, o11.received_params().size()); - ViewObserver::TreeChangeParams p11; - p11 = p1; - p11.receiver = &v11; - EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().front())); - - // v12 should see changed notifications. - EXPECT_EQ(2U, o12.received_params().size()); - ViewObserver::TreeChangeParams p12; - p12 = p1; - p12.receiver = &v12; - EXPECT_TRUE(TreeChangeParamsMatch(p12, o12.received_params().back())); - - // v111 should see both changing and changed notifications. - EXPECT_EQ(2U, o111.received_params().size()); - ViewObserver::TreeChangeParams p111; - p111 = p1; - p111.receiver = &v111; - EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().front())); - EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().back())); -} - -namespace { - -class OrderChangeObserver : public ViewObserver { - public: - struct Change { - View* view; - View* relative_view; - mojo::OrderDirection direction; - }; - typedef std::vector<Change> Changes; - - explicit OrderChangeObserver(View* observee) : observee_(observee) { - observee_->AddObserver(this); - } - ~OrderChangeObserver() override { observee_->RemoveObserver(this); } - - Changes GetAndClearChanges() { - Changes changes; - changes_.swap(changes); - return changes; - } - - private: - // Overridden from ViewObserver: - void OnViewReordering(View* view, - View* relative_view, - mojo::OrderDirection direction) override { - OnViewReordered(view, relative_view, direction); - } - - void OnViewReordered(View* view, - View* relative_view, - mojo::OrderDirection direction) override { - Change change; - change.view = view; - change.relative_view = relative_view; - change.direction = direction; - changes_.push_back(change); - } - - View* observee_; - Changes changes_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(OrderChangeObserver); -}; - -} // namespace - -TEST_F(ViewObserverTest, Order) { - TestView v1, v11, v12, v13; - v1.AddChild(&v11); - v1.AddChild(&v12); - v1.AddChild(&v13); - - // Order: v11, v12, v13 - EXPECT_EQ(3U, v1.children().size()); - EXPECT_EQ(&v11, v1.children().front()); - EXPECT_EQ(&v13, v1.children().back()); - - { - OrderChangeObserver observer(&v11); - - // Move v11 to front. - // Resulting order: v12, v13, v11 - v11.MoveToFront(); - EXPECT_EQ(&v12, v1.children().front()); - EXPECT_EQ(&v11, v1.children().back()); - - OrderChangeObserver::Changes changes = observer.GetAndClearChanges(); - ASSERT_EQ(2U, changes.size()); - EXPECT_EQ(&v11, changes[0].view); - EXPECT_EQ(&v13, changes[0].relative_view); - EXPECT_EQ(mojo::ORDER_DIRECTION_ABOVE, changes[0].direction); - - EXPECT_EQ(&v11, changes[1].view); - EXPECT_EQ(&v13, changes[1].relative_view); - EXPECT_EQ(mojo::ORDER_DIRECTION_ABOVE, changes[1].direction); - } - - { - OrderChangeObserver observer(&v11); - - // Move v11 to back. - // Resulting order: v11, v12, v13 - v11.MoveToBack(); - EXPECT_EQ(&v11, v1.children().front()); - EXPECT_EQ(&v13, v1.children().back()); - - OrderChangeObserver::Changes changes = observer.GetAndClearChanges(); - ASSERT_EQ(2U, changes.size()); - EXPECT_EQ(&v11, changes[0].view); - EXPECT_EQ(&v12, changes[0].relative_view); - EXPECT_EQ(mojo::ORDER_DIRECTION_BELOW, changes[0].direction); - - EXPECT_EQ(&v11, changes[1].view); - EXPECT_EQ(&v12, changes[1].relative_view); - EXPECT_EQ(mojo::ORDER_DIRECTION_BELOW, changes[1].direction); - } - - { - OrderChangeObserver observer(&v11); - - // Move v11 above v12. - // Resulting order: v12. v11, v13 - v11.Reorder(&v12, mojo::ORDER_DIRECTION_ABOVE); - EXPECT_EQ(&v12, v1.children().front()); - EXPECT_EQ(&v13, v1.children().back()); - - OrderChangeObserver::Changes changes = observer.GetAndClearChanges(); - ASSERT_EQ(2U, changes.size()); - EXPECT_EQ(&v11, changes[0].view); - EXPECT_EQ(&v12, changes[0].relative_view); - EXPECT_EQ(mojo::ORDER_DIRECTION_ABOVE, changes[0].direction); - - EXPECT_EQ(&v11, changes[1].view); - EXPECT_EQ(&v12, changes[1].relative_view); - EXPECT_EQ(mojo::ORDER_DIRECTION_ABOVE, changes[1].direction); - } - - { - OrderChangeObserver observer(&v11); - - // Move v11 below v12. - // Resulting order: v11, v12, v13 - v11.Reorder(&v12, mojo::ORDER_DIRECTION_BELOW); - EXPECT_EQ(&v11, v1.children().front()); - EXPECT_EQ(&v13, v1.children().back()); - - OrderChangeObserver::Changes changes = observer.GetAndClearChanges(); - ASSERT_EQ(2U, changes.size()); - EXPECT_EQ(&v11, changes[0].view); - EXPECT_EQ(&v12, changes[0].relative_view); - EXPECT_EQ(mojo::ORDER_DIRECTION_BELOW, changes[0].direction); - - EXPECT_EQ(&v11, changes[1].view); - EXPECT_EQ(&v12, changes[1].relative_view); - EXPECT_EQ(mojo::ORDER_DIRECTION_BELOW, changes[1].direction); - } -} - -namespace { - -typedef std::vector<std::string> Changes; - -std::string ViewIdToString(Id id) { - return (id == 0) ? "null" - : base::StringPrintf("%d,%d", HiWord(id), LoWord(id)); -} - -std::string RectToString(const mojo::Rect& rect) { - return base::StringPrintf("%d,%d %dx%d", rect.x, rect.y, rect.width, - rect.height); -} - -class BoundsChangeObserver : public ViewObserver { - public: - explicit BoundsChangeObserver(View* view) : view_(view) { - view_->AddObserver(this); - } - ~BoundsChangeObserver() override { view_->RemoveObserver(this); } - - Changes GetAndClearChanges() { - Changes changes; - changes.swap(changes_); - return changes; - } - - private: - // Overridden from ViewObserver: - void OnViewBoundsChanging(View* view, - const mojo::Rect& old_bounds, - const mojo::Rect& new_bounds) override { - changes_.push_back(base::StringPrintf( - "view=%s old_bounds=%s new_bounds=%s phase=changing", - ViewIdToString(view->id()).c_str(), RectToString(old_bounds).c_str(), - RectToString(new_bounds).c_str())); - } - void OnViewBoundsChanged(View* view, - const mojo::Rect& old_bounds, - const mojo::Rect& new_bounds) override { - changes_.push_back(base::StringPrintf( - "view=%s old_bounds=%s new_bounds=%s phase=changed", - ViewIdToString(view->id()).c_str(), RectToString(old_bounds).c_str(), - RectToString(new_bounds).c_str())); - } - - View* view_; - Changes changes_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(BoundsChangeObserver); -}; - -} // namespace - -TEST_F(ViewObserverTest, SetBounds) { - TestView v1; - { - BoundsChangeObserver observer(&v1); - mojo::Rect rect; - rect.width = rect.height = 100; - v1.SetBounds(rect); - - Changes changes = observer.GetAndClearChanges(); - ASSERT_EQ(2U, changes.size()); - EXPECT_EQ( - "view=0,1 old_bounds=0,0 0x0 new_bounds=0,0 100x100 phase=changing", - changes[0]); - EXPECT_EQ( - "view=0,1 old_bounds=0,0 0x0 new_bounds=0,0 100x100 phase=changed", - changes[1]); - } -} - -namespace { - -class VisibilityChangeObserver : public ViewObserver { - public: - explicit VisibilityChangeObserver(View* view) : view_(view) { - view_->AddObserver(this); - } - ~VisibilityChangeObserver() override { view_->RemoveObserver(this); } - - Changes GetAndClearChanges() { - Changes changes; - changes.swap(changes_); - return changes; - } - - private: - // Overridden from ViewObserver: - void OnViewVisibilityChanging(View* view) override { - changes_.push_back( - base::StringPrintf("view=%s phase=changing visibility=%s", - ViewIdToString(view->id()).c_str(), - view->visible() ? "true" : "false")); - } - void OnViewVisibilityChanged(View* view) override { - changes_.push_back(base::StringPrintf("view=%s phase=changed visibility=%s", - ViewIdToString(view->id()).c_str(), - view->visible() ? "true" : "false")); - } - - View* view_; - Changes changes_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(VisibilityChangeObserver); -}; - -} // namespace - -TEST_F(ViewObserverTest, SetVisible) { - TestView v1; - EXPECT_TRUE(v1.visible()); - { - // Change visibility from true to false and make sure we get notifications. - VisibilityChangeObserver observer(&v1); - v1.SetVisible(false); - - Changes changes = observer.GetAndClearChanges(); - ASSERT_EQ(2U, changes.size()); - EXPECT_EQ("view=0,1 phase=changing visibility=true", changes[0]); - EXPECT_EQ("view=0,1 phase=changed visibility=false", changes[1]); - } - { - // Set visible to existing value and verify no notifications. - VisibilityChangeObserver observer(&v1); - v1.SetVisible(false); - EXPECT_TRUE(observer.GetAndClearChanges().empty()); - } -} - -TEST_F(ViewObserverTest, SetVisibleParent) { - TestView parent; - ViewPrivate(&parent).set_id(1); - TestView child; - ViewPrivate(&child).set_id(2); - parent.AddChild(&child); - EXPECT_TRUE(parent.visible()); - EXPECT_TRUE(child.visible()); - { - // Change visibility from true to false and make sure we get notifications - // on the parent. - VisibilityChangeObserver observer(&parent); - child.SetVisible(false); - - Changes changes = observer.GetAndClearChanges(); - ASSERT_EQ(1U, changes.size()); - EXPECT_EQ("view=0,2 phase=changed visibility=false", changes[0]); - } -} - -TEST_F(ViewObserverTest, SetVisibleChild) { - TestView parent; - ViewPrivate(&parent).set_id(1); - TestView child; - ViewPrivate(&child).set_id(2); - parent.AddChild(&child); - EXPECT_TRUE(parent.visible()); - EXPECT_TRUE(child.visible()); - { - // Change visibility from true to false and make sure we get notifications - // on the child. - VisibilityChangeObserver observer(&child); - parent.SetVisible(false); - - Changes changes = observer.GetAndClearChanges(); - ASSERT_EQ(1U, changes.size()); - EXPECT_EQ("view=0,1 phase=changed visibility=false", changes[0]); - } -} - -namespace { - -class SharedPropertyChangeObserver : public ViewObserver { - public: - explicit SharedPropertyChangeObserver(View* view) : view_(view) { - view_->AddObserver(this); - } - ~SharedPropertyChangeObserver() override { view_->RemoveObserver(this); } - - Changes GetAndClearChanges() { - Changes changes; - changes.swap(changes_); - return changes; - } - - private: - // Overridden from ViewObserver: - void OnViewSharedPropertyChanged( - View* view, - const std::string& name, - const std::vector<uint8_t>* old_data, - const std::vector<uint8_t>* new_data) override { - changes_.push_back(base::StringPrintf( - "view=%s shared property changed key=%s old_value=%s new_value=%s", - ViewIdToString(view->id()).c_str(), name.c_str(), - VectorToString(old_data).c_str(), VectorToString(new_data).c_str())); - } - - std::string VectorToString(const std::vector<uint8_t>* data) { - if (!data) - return "NULL"; - std::string s; - for (char c : *data) - s += c; - return s; - } - - View* view_; - Changes changes_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(SharedPropertyChangeObserver); -}; - -} // namespace - -TEST_F(ViewObserverTest, SetLocalProperty) { - TestView v1; - std::vector<uint8_t> one(1, '1'); - - { - // Change visibility from true to false and make sure we get notifications. - SharedPropertyChangeObserver observer(&v1); - v1.SetSharedProperty("one", &one); - Changes changes = observer.GetAndClearChanges(); - ASSERT_EQ(1U, changes.size()); - EXPECT_EQ( - "view=0,1 shared property changed key=one old_value=NULL new_value=1", - changes[0]); - EXPECT_EQ(1U, v1.shared_properties().size()); - } - { - // Set visible to existing value and verify no notifications. - SharedPropertyChangeObserver observer(&v1); - v1.SetSharedProperty("one", &one); - EXPECT_TRUE(observer.GetAndClearChanges().empty()); - EXPECT_EQ(1U, v1.shared_properties().size()); - } - { - // Set the value to NULL to delete it. - // Change visibility from true to false and make sure we get notifications. - SharedPropertyChangeObserver observer(&v1); - v1.SetSharedProperty("one", NULL); - Changes changes = observer.GetAndClearChanges(); - ASSERT_EQ(1U, changes.size()); - EXPECT_EQ( - "view=0,1 shared property changed key=one old_value=1 new_value=NULL", - changes[0]); - EXPECT_EQ(0U, v1.shared_properties().size()); - } - { - // Setting a null property to null shouldn't update us. - SharedPropertyChangeObserver observer(&v1); - v1.SetSharedProperty("one", NULL); - EXPECT_TRUE(observer.GetAndClearChanges().empty()); - EXPECT_EQ(0U, v1.shared_properties().size()); - } -} - -namespace { - -typedef std::pair<const void*, intptr_t> PropertyChangeInfo; - -class LocalPropertyChangeObserver : public ViewObserver { - public: - explicit LocalPropertyChangeObserver(View* view) - : view_(view), property_key_(nullptr), old_property_value_(-1) { - view_->AddObserver(this); - } - ~LocalPropertyChangeObserver() override { view_->RemoveObserver(this); } - - PropertyChangeInfo PropertyChangeInfoAndClear() { - PropertyChangeInfo result(property_key_, old_property_value_); - property_key_ = NULL; - old_property_value_ = -3; - return result; - } - - private: - void OnViewLocalPropertyChanged(View* window, - const void* key, - intptr_t old) override { - property_key_ = key; - old_property_value_ = old; - } - - View* view_; - const void* property_key_; - intptr_t old_property_value_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(LocalPropertyChangeObserver); -}; - -} // namespace - -TEST_F(ViewObserverTest, LocalPropertyChanged) { - TestView v1; - LocalPropertyChangeObserver o(&v1); - - static const ViewProperty<int> prop = {-2}; - - v1.SetLocalProperty(&prop, 1); - EXPECT_EQ(PropertyChangeInfo(&prop, -2), o.PropertyChangeInfoAndClear()); - v1.SetLocalProperty(&prop, -2); - EXPECT_EQ(PropertyChangeInfo(&prop, 1), o.PropertyChangeInfoAndClear()); - v1.SetLocalProperty(&prop, 3); - EXPECT_EQ(PropertyChangeInfo(&prop, -2), o.PropertyChangeInfoAndClear()); - v1.ClearLocalProperty(&prop); - EXPECT_EQ(PropertyChangeInfo(&prop, 3), o.PropertyChangeInfoAndClear()); - - // Sanity check to see if |PropertyChangeInfoAndClear| really clears. - EXPECT_EQ(PropertyChangeInfo(reinterpret_cast<const void*>(NULL), -3), - o.PropertyChangeInfoAndClear()); -} - -} // namespace mus
diff --git a/components/mus/public/cpp/tests/view_manager_test_base.cc b/components/mus/public/cpp/tests/window_server_test_base.cc similarity index 62% rename from components/mus/public/cpp/tests/view_manager_test_base.cc rename to components/mus/public/cpp/tests/window_server_test_base.cc index e4bf2ba..649fc24 100644 --- a/components/mus/public/cpp/tests/view_manager_test_base.cc +++ b/components/mus/public/cpp/tests/window_server_test_base.cc
@@ -2,15 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/mus/public/cpp/tests/view_manager_test_base.h" +#include "components/mus/public/cpp/tests/window_server_test_base.h" #include "base/bind.h" #include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/test/test_timeouts.h" -#include "components/mus/public/cpp/view.h" -#include "components/mus/public/cpp/view_tree_connection.h" -#include "components/mus/public/cpp/view_tree_host_factory.h" +#include "components/mus/public/cpp/window.h" +#include "components/mus/public/cpp/window_tree_connection.h" +#include "components/mus/public/cpp/window_tree_host_factory.h" #include "mojo/application/public/cpp/application_impl.h" namespace mus { @@ -26,15 +26,15 @@ } // namespace -ViewManagerTestBase::ViewManagerTestBase() +WindowServerTestBase::WindowServerTestBase() : most_recent_connection_(nullptr), window_manager_(nullptr), - view_tree_connection_destroyed_(false) {} + window_tree_connection_destroyed_(false) {} -ViewManagerTestBase::~ViewManagerTestBase() {} +WindowServerTestBase::~WindowServerTestBase() {} // static -bool ViewManagerTestBase::DoRunLoopWithTimeout() { +bool WindowServerTestBase::DoRunLoopWithTimeout() { if (current_run_loop != nullptr) return false; @@ -51,7 +51,7 @@ } // static -bool ViewManagerTestBase::QuitRunLoop() { +bool WindowServerTestBase::QuitRunLoop() { if (!current_run_loop) return false; @@ -60,44 +60,44 @@ return true; } -void ViewManagerTestBase::SetUp() { +void WindowServerTestBase::SetUp() { ApplicationTestBase::SetUp(); - CreateSingleViewTreeHost(application_impl(), this, &host_); + CreateSingleWindowTreeHost(application_impl(), this, &host_); ASSERT_TRUE(DoRunLoopWithTimeout()); // RunLoop should be quit by OnEmbed(). std::swap(window_manager_, most_recent_connection_); } -void ViewManagerTestBase::TearDown() { +void WindowServerTestBase::TearDown() { ApplicationTestBase::TearDown(); } -mojo::ApplicationDelegate* ViewManagerTestBase::GetApplicationDelegate() { +mojo::ApplicationDelegate* WindowServerTestBase::GetApplicationDelegate() { return this; } -bool ViewManagerTestBase::ConfigureIncomingConnection( +bool WindowServerTestBase::ConfigureIncomingConnection( mojo::ApplicationConnection* connection) { connection->AddService<mojo::ViewTreeClient>(this); return true; } -void ViewManagerTestBase::OnEmbed(View* root) { +void WindowServerTestBase::OnEmbed(Window* root) { most_recent_connection_ = root->connection(); EXPECT_TRUE(QuitRunLoop()); } -void ViewManagerTestBase::OnConnectionLost(ViewTreeConnection* connection) { - view_tree_connection_destroyed_ = true; +void WindowServerTestBase::OnConnectionLost(WindowTreeConnection* connection) { + window_tree_connection_destroyed_ = true; } -void ViewManagerTestBase::Create( +void WindowServerTestBase::Create( mojo::ApplicationConnection* connection, mojo::InterfaceRequest<mojo::ViewTreeClient> request) { - ViewTreeConnection::Create( + WindowTreeConnection::Create( this, request.Pass(), - ViewTreeConnection::CreateType::DONT_WAIT_FOR_EMBED); + WindowTreeConnection::CreateType::DONT_WAIT_FOR_EMBED); } } // namespace mus
diff --git a/components/mus/public/cpp/tests/view_manager_test_base.h b/components/mus/public/cpp/tests/window_server_test_base.h similarity index 63% rename from components/mus/public/cpp/tests/view_manager_test_base.h rename to components/mus/public/cpp/tests/window_server_test_base.h index a1529f3..b46c871 100644 --- a/components/mus/public/cpp/tests/view_manager_test_base.h +++ b/components/mus/public/cpp/tests/window_server_test_base.h
@@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_MUS_PUBLIC_CPP_TESTS_VIEW_MANAGER_TEST_BASE_H_ -#define COMPONENTS_MUS_PUBLIC_CPP_TESTS_VIEW_MANAGER_TEST_BASE_H_ +#ifndef COMPONENTS_MUS_PUBLIC_CPP_TESTS_WINDOW_SERVER_TEST_BASE_H_ +#define COMPONENTS_MUS_PUBLIC_CPP_TESTS_WINDOW_SERVER_TEST_BASE_H_ #include "base/memory/scoped_ptr.h" -#include "components/mus/public/cpp/view_tree_delegate.h" +#include "components/mus/public/cpp/window_tree_delegate.h" #include "components/mus/public/interfaces/view_tree.mojom.h" #include "components/mus/public/interfaces/view_tree_host.mojom.h" #include "mojo/application/public/cpp/application_delegate.h" @@ -15,22 +15,22 @@ namespace mus { -// ViewManagerTestBase is a base class for use with app tests that use -// ViewManager. SetUp() connects to the ViewManager and blocks until OnEmbed() -// has been invoked. window_manager() can be used to access the ViewManager +// WindowServerTestBase is a base class for use with app tests that use +// WindowServer. SetUp() connects to the WindowServer and blocks until OnEmbed() +// has been invoked. window_manager() can be used to access the WindowServer // established as part of SetUp(). -class ViewManagerTestBase +class WindowServerTestBase : public mojo::test::ApplicationTestBase, public mojo::ApplicationDelegate, - public ViewTreeDelegate, + public WindowTreeDelegate, public mojo::InterfaceFactory<mojo::ViewTreeClient> { public: - ViewManagerTestBase(); - ~ViewManagerTestBase() override; + WindowServerTestBase(); + ~WindowServerTestBase() override; - // True if ViewTreeDelegate::OnConnectionLost() was called. - bool view_tree_connection_destroyed() const { - return view_tree_connection_destroyed_; + // True if WindowTreeDelegate::OnConnectionLost() was called. + bool window_tree_connection_destroyed() const { + return window_tree_connection_destroyed_; } // Runs the MessageLoop until QuitRunLoop() is called, or a timeout occurs. @@ -42,10 +42,10 @@ // success, false if a RunLoop isn't running. static bool QuitRunLoop() WARN_UNUSED_RESULT; - ViewTreeConnection* window_manager() { return window_manager_; } + WindowTreeConnection* window_manager() { return window_manager_; } protected: - ViewTreeConnection* most_recent_connection() { + WindowTreeConnection* most_recent_connection() { return most_recent_connection_; } @@ -60,9 +60,9 @@ bool ConfigureIncomingConnection( mojo::ApplicationConnection* connection) override; - // ViewTreeDelegate: - void OnEmbed(View* root) override; - void OnConnectionLost(ViewTreeConnection* connection) override; + // WindowTreeDelegate: + void OnEmbed(Window* root) override; + void OnConnectionLost(WindowTreeConnection* connection) override; // InterfaceFactory<ViewTreeClient>: void Create(mojo::ApplicationConnection* connection, @@ -70,20 +70,20 @@ // Used to receive the most recent view tree connection loaded by an embed // action. - ViewTreeConnection* most_recent_connection_; + WindowTreeConnection* most_recent_connection_; private: mojo::ViewTreeHostPtr host_; // The View Manager connection held by the window manager (app running at the // root view). - ViewTreeConnection* window_manager_; + WindowTreeConnection* window_manager_; - bool view_tree_connection_destroyed_; + bool window_tree_connection_destroyed_; - MOJO_DISALLOW_COPY_AND_ASSIGN(ViewManagerTestBase); + MOJO_DISALLOW_COPY_AND_ASSIGN(WindowServerTestBase); }; } // namespace mus -#endif // COMPONENTS_MUS_PUBLIC_CPP_TESTS_VIEW_MANAGER_TEST_BASE_H_ +#endif // COMPONENTS_MUS_PUBLIC_CPP_TESTS_WINDOW_SERVER_TEST_BASE_H_
diff --git a/components/mus/public/cpp/tests/view_manager_test_suite.cc b/components/mus/public/cpp/tests/window_server_test_suite.cc similarity index 75% rename from components/mus/public/cpp/tests/view_manager_test_suite.cc rename to components/mus/public/cpp/tests/window_server_test_suite.cc index a1e0c98d..ea1a04c0 100644 --- a/components/mus/public/cpp/tests/view_manager_test_suite.cc +++ b/components/mus/public/cpp/tests/window_server_test_suite.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/mus/public/cpp/tests/view_manager_test_suite.h" +#include "components/mus/public/cpp/tests/window_server_test_suite.h" #include "base/i18n/icu_util.h" @@ -12,12 +12,12 @@ namespace mus { -ViewManagerTestSuite::ViewManagerTestSuite(int argc, char** argv) +WindowServerTestSuite::WindowServerTestSuite(int argc, char** argv) : TestSuite(argc, argv) {} -ViewManagerTestSuite::~ViewManagerTestSuite() {} +WindowServerTestSuite::~WindowServerTestSuite() {} -void ViewManagerTestSuite::Initialize() { +void WindowServerTestSuite::Initialize() { #if defined(USE_X11) // Each test ends up creating a new thread for the native viewport service. // In other words we'll use X on different threads, so tell it that.
diff --git a/components/mus/public/cpp/tests/window_server_test_suite.h b/components/mus/public/cpp/tests/window_server_test_suite.h new file mode 100644 index 0000000..cbc2eb77 --- /dev/null +++ b/components/mus/public/cpp/tests/window_server_test_suite.h
@@ -0,0 +1,27 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_MUS_PUBLIC_CPP_TESTS_WINDOW_SERVER_TEST_SUITE_H_ +#define COMPONENTS_MUS_PUBLIC_CPP_TESTS_WINDOW_SERVER_TEST_SUITE_H_ + +#include "base/test/test_suite.h" +#include "third_party/mojo/src/mojo/public/cpp/system/macros.h" + +namespace mus { + +class WindowServerTestSuite : public base::TestSuite { + public: + WindowServerTestSuite(int argc, char** argv); + ~WindowServerTestSuite() override; + + protected: + void Initialize() override; + + private: + MOJO_DISALLOW_COPY_AND_ASSIGN(WindowServerTestSuite); +}; + +} // namespace mus + +#endif // COMPONENTS_MUS_PUBLIC_CPP_TESTS_WINDOW_SERVER_TEST_SUITE_H_
diff --git a/components/mus/public/cpp/tests/window_unittest.cc b/components/mus/public/cpp/tests/window_unittest.cc new file mode 100644 index 0000000..870a026 --- /dev/null +++ b/components/mus/public/cpp/tests/window_unittest.cc
@@ -0,0 +1,875 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/mus/public/cpp/window.h" + +#include "base/logging.h" +#include "base/strings/stringprintf.h" +#include "components/mus/public/cpp/lib/window_private.h" +#include "components/mus/public/cpp/util.h" +#include "components/mus/public/cpp/window_observer.h" +#include "components/mus/public/cpp/window_property.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace mus { + +// Window --------------------------------------------------------------------- + +typedef testing::Test WindowTest; + +// Subclass with public ctor/dtor. +class TestWindow : public Window { + public: + TestWindow() { WindowPrivate(this).set_id(1); } + ~TestWindow() {} + + private: + MOJO_DISALLOW_COPY_AND_ASSIGN(TestWindow); +}; + +TEST_F(WindowTest, AddChild) { + TestWindow w1; + TestWindow w11; + w1.AddChild(&w11); + EXPECT_EQ(1U, w1.children().size()); +} + +TEST_F(WindowTest, RemoveChild) { + TestWindow w1; + TestWindow w11; + w1.AddChild(&w11); + EXPECT_EQ(1U, w1.children().size()); + w1.RemoveChild(&w11); + EXPECT_EQ(0U, w1.children().size()); +} + +TEST_F(WindowTest, Reparent) { + TestWindow w1; + TestWindow w2; + TestWindow w11; + w1.AddChild(&w11); + EXPECT_EQ(1U, w1.children().size()); + w2.AddChild(&w11); + EXPECT_EQ(1U, w2.children().size()); + EXPECT_EQ(0U, w1.children().size()); +} + +TEST_F(WindowTest, Contains) { + TestWindow w1; + + // Direct descendant. + TestWindow w11; + w1.AddChild(&w11); + EXPECT_TRUE(w1.Contains(&w11)); + + // Indirect descendant. + TestWindow w111; + w11.AddChild(&w111); + EXPECT_TRUE(w1.Contains(&w111)); +} + +TEST_F(WindowTest, GetChildById) { + TestWindow w1; + WindowPrivate(&w1).set_id(1); + TestWindow w11; + WindowPrivate(&w11).set_id(11); + w1.AddChild(&w11); + TestWindow w111; + WindowPrivate(&w111).set_id(111); + w11.AddChild(&w111); + + // Find direct & indirect descendents. + EXPECT_EQ(&w11, w1.GetChildById(w11.id())); + EXPECT_EQ(&w111, w1.GetChildById(w111.id())); +} + +TEST_F(WindowTest, DrawnAndVisible) { + TestWindow w1; + EXPECT_TRUE(w1.visible()); + EXPECT_FALSE(w1.IsDrawn()); + + WindowPrivate(&w1).set_drawn(true); + + TestWindow w11; + w1.AddChild(&w11); + EXPECT_TRUE(w11.visible()); + EXPECT_TRUE(w11.IsDrawn()); + + w1.RemoveChild(&w11); + EXPECT_TRUE(w11.visible()); + EXPECT_FALSE(w11.IsDrawn()); +} + +namespace { +DEFINE_WINDOW_PROPERTY_KEY(int, kIntKey, -2); +DEFINE_WINDOW_PROPERTY_KEY(const char*, kStringKey, "squeamish"); +} + +TEST_F(WindowTest, Property) { + TestWindow w; + + // Non-existent properties should return the default walues. + EXPECT_EQ(-2, w.GetLocalProperty(kIntKey)); + EXPECT_EQ(std::string("squeamish"), w.GetLocalProperty(kStringKey)); + + // A set property walue should be returned again (even if it's the default + // walue). + w.SetLocalProperty(kIntKey, INT_MAX); + EXPECT_EQ(INT_MAX, w.GetLocalProperty(kIntKey)); + w.SetLocalProperty(kIntKey, -2); + EXPECT_EQ(-2, w.GetLocalProperty(kIntKey)); + w.SetLocalProperty(kIntKey, INT_MIN); + EXPECT_EQ(INT_MIN, w.GetLocalProperty(kIntKey)); + + w.SetLocalProperty(kStringKey, static_cast<const char*>(NULL)); + EXPECT_EQ(NULL, w.GetLocalProperty(kStringKey)); + w.SetLocalProperty(kStringKey, "squeamish"); + EXPECT_EQ(std::string("squeamish"), w.GetLocalProperty(kStringKey)); + w.SetLocalProperty(kStringKey, "ossifrage"); + EXPECT_EQ(std::string("ossifrage"), w.GetLocalProperty(kStringKey)); + + // ClearProperty should restore the default walue. + w.ClearLocalProperty(kIntKey); + EXPECT_EQ(-2, w.GetLocalProperty(kIntKey)); + w.ClearLocalProperty(kStringKey); + EXPECT_EQ(std::string("squeamish"), w.GetLocalProperty(kStringKey)); +} + +namespace { + +class TestProperty { + public: + TestProperty() {} + virtual ~TestProperty() { last_deleted_ = this; } + static TestProperty* last_deleted() { return last_deleted_; } + + private: + static TestProperty* last_deleted_; + MOJO_DISALLOW_COPY_AND_ASSIGN(TestProperty); +}; + +TestProperty* TestProperty::last_deleted_ = NULL; + +DEFINE_OWNED_WINDOW_PROPERTY_KEY(TestProperty, kOwnedKey, NULL); + +} // namespace + +TEST_F(WindowTest, OwnedProperty) { + TestProperty* p3 = NULL; + { + TestWindow w; + EXPECT_EQ(NULL, w.GetLocalProperty(kOwnedKey)); + TestProperty* p1 = new TestProperty(); + w.SetLocalProperty(kOwnedKey, p1); + EXPECT_EQ(p1, w.GetLocalProperty(kOwnedKey)); + EXPECT_EQ(NULL, TestProperty::last_deleted()); + + TestProperty* p2 = new TestProperty(); + w.SetLocalProperty(kOwnedKey, p2); + EXPECT_EQ(p2, w.GetLocalProperty(kOwnedKey)); + EXPECT_EQ(p1, TestProperty::last_deleted()); + + w.ClearLocalProperty(kOwnedKey); + EXPECT_EQ(NULL, w.GetLocalProperty(kOwnedKey)); + EXPECT_EQ(p2, TestProperty::last_deleted()); + + p3 = new TestProperty(); + w.SetLocalProperty(kOwnedKey, p3); + EXPECT_EQ(p3, w.GetLocalProperty(kOwnedKey)); + EXPECT_EQ(p2, TestProperty::last_deleted()); + } + + EXPECT_EQ(p3, TestProperty::last_deleted()); +} + +// WindowObserver -------------------------------------------------------- + +typedef testing::Test WindowObserverTest; + +bool TreeChangeParamsMatch(const WindowObserver::TreeChangeParams& lhs, + const WindowObserver::TreeChangeParams& rhs) { + return lhs.target == rhs.target && lhs.old_parent == rhs.old_parent && + lhs.new_parent == rhs.new_parent && lhs.receiver == rhs.receiver; +} + +class TreeChangeObserver : public WindowObserver { + public: + explicit TreeChangeObserver(Window* observee) : observee_(observee) { + observee_->AddObserver(this); + } + ~TreeChangeObserver() override { observee_->RemoveObserver(this); } + + void Reset() { received_params_.clear(); } + + const std::vector<TreeChangeParams>& received_params() { + return received_params_; + } + + private: + // Overridden from WindowObserver: + void OnTreeChanging(const TreeChangeParams& params) override { + received_params_.push_back(params); + } + void OnTreeChanged(const TreeChangeParams& params) override { + received_params_.push_back(params); + } + + Window* observee_; + std::vector<TreeChangeParams> received_params_; + + MOJO_DISALLOW_COPY_AND_ASSIGN(TreeChangeObserver); +}; + +// Adds/Removes w11 to w1. +TEST_F(WindowObserverTest, TreeChange_SimpleAddRemove) { + TestWindow w1; + TreeChangeObserver o1(&w1); + EXPECT_TRUE(o1.received_params().empty()); + + TestWindow w11; + TreeChangeObserver o11(&w11); + EXPECT_TRUE(o11.received_params().empty()); + + // Add. + + w1.AddChild(&w11); + + EXPECT_EQ(2U, o1.received_params().size()); + WindowObserver::TreeChangeParams p1; + p1.target = &w11; + p1.receiver = &w1; + p1.old_parent = NULL; + p1.new_parent = &w1; + EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().back())); + + EXPECT_EQ(2U, o11.received_params().size()); + WindowObserver::TreeChangeParams p11 = p1; + p11.receiver = &w11; + EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().front())); + EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().back())); + + o1.Reset(); + o11.Reset(); + EXPECT_TRUE(o1.received_params().empty()); + EXPECT_TRUE(o11.received_params().empty()); + + // Remove. + + w1.RemoveChild(&w11); + + EXPECT_EQ(2U, o1.received_params().size()); + p1.target = &w11; + p1.receiver = &w1; + p1.old_parent = &w1; + p1.new_parent = NULL; + EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().front())); + + EXPECT_EQ(2U, o11.received_params().size()); + p11 = p1; + p11.receiver = &w11; + EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().front())); + EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().back())); +} + +// Creates these two trees: +// w1 +// +- w11 +// w111 +// +- w1111 +// +- w1112 +// Then adds/removes w111 from w11. +TEST_F(WindowObserverTest, TreeChange_NestedAddRemove) { + TestWindow w1, w11, w111, w1111, w1112; + + // Root tree. + w1.AddChild(&w11); + + // Tree to be attached. + w111.AddChild(&w1111); + w111.AddChild(&w1112); + + TreeChangeObserver o1(&w1), o11(&w11), o111(&w111), o1111(&w1111), + o1112(&w1112); + WindowObserver::TreeChangeParams p1, p11, p111, p1111, p1112; + + // Add. + + w11.AddChild(&w111); + + EXPECT_EQ(2U, o1.received_params().size()); + p1.target = &w111; + p1.receiver = &w1; + p1.old_parent = NULL; + p1.new_parent = &w11; + EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().back())); + + EXPECT_EQ(2U, o11.received_params().size()); + p11 = p1; + p11.receiver = &w11; + EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().back())); + + EXPECT_EQ(2U, o111.received_params().size()); + p111 = p11; + p111.receiver = &w111; + EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().front())); + EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().back())); + + EXPECT_EQ(2U, o1111.received_params().size()); + p1111 = p111; + p1111.receiver = &w1111; + EXPECT_TRUE(TreeChangeParamsMatch(p1111, o1111.received_params().front())); + EXPECT_TRUE(TreeChangeParamsMatch(p1111, o1111.received_params().back())); + + EXPECT_EQ(2U, o1112.received_params().size()); + p1112 = p111; + p1112.receiver = &w1112; + EXPECT_TRUE(TreeChangeParamsMatch(p1112, o1112.received_params().front())); + EXPECT_TRUE(TreeChangeParamsMatch(p1112, o1112.received_params().back())); + + // Remove. + o1.Reset(); + o11.Reset(); + o111.Reset(); + o1111.Reset(); + o1112.Reset(); + EXPECT_TRUE(o1.received_params().empty()); + EXPECT_TRUE(o11.received_params().empty()); + EXPECT_TRUE(o111.received_params().empty()); + EXPECT_TRUE(o1111.received_params().empty()); + EXPECT_TRUE(o1112.received_params().empty()); + + w11.RemoveChild(&w111); + + EXPECT_EQ(2U, o1.received_params().size()); + p1.target = &w111; + p1.receiver = &w1; + p1.old_parent = &w11; + p1.new_parent = NULL; + EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().front())); + + EXPECT_EQ(2U, o11.received_params().size()); + p11 = p1; + p11.receiver = &w11; + EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().front())); + + EXPECT_EQ(2U, o111.received_params().size()); + p111 = p11; + p111.receiver = &w111; + EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().front())); + EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().back())); + + EXPECT_EQ(2U, o1111.received_params().size()); + p1111 = p111; + p1111.receiver = &w1111; + EXPECT_TRUE(TreeChangeParamsMatch(p1111, o1111.received_params().front())); + EXPECT_TRUE(TreeChangeParamsMatch(p1111, o1111.received_params().back())); + + EXPECT_EQ(2U, o1112.received_params().size()); + p1112 = p111; + p1112.receiver = &w1112; + EXPECT_TRUE(TreeChangeParamsMatch(p1112, o1112.received_params().front())); + EXPECT_TRUE(TreeChangeParamsMatch(p1112, o1112.received_params().back())); +} + +TEST_F(WindowObserverTest, TreeChange_Reparent) { + TestWindow w1, w11, w12, w111; + w1.AddChild(&w11); + w1.AddChild(&w12); + w11.AddChild(&w111); + + TreeChangeObserver o1(&w1), o11(&w11), o12(&w12), o111(&w111); + + // Reparent. + w12.AddChild(&w111); + + // w1 (root) should see both changing and changed notifications. + EXPECT_EQ(4U, o1.received_params().size()); + WindowObserver::TreeChangeParams p1; + p1.target = &w111; + p1.receiver = &w1; + p1.old_parent = &w11; + p1.new_parent = &w12; + EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().front())); + EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().back())); + + // w11 should see changing notifications. + EXPECT_EQ(2U, o11.received_params().size()); + WindowObserver::TreeChangeParams p11; + p11 = p1; + p11.receiver = &w11; + EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().front())); + + // w12 should see changed notifications. + EXPECT_EQ(2U, o12.received_params().size()); + WindowObserver::TreeChangeParams p12; + p12 = p1; + p12.receiver = &w12; + EXPECT_TRUE(TreeChangeParamsMatch(p12, o12.received_params().back())); + + // w111 should see both changing and changed notifications. + EXPECT_EQ(2U, o111.received_params().size()); + WindowObserver::TreeChangeParams p111; + p111 = p1; + p111.receiver = &w111; + EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().front())); + EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().back())); +} + +namespace { + +class OrderChangeObserver : public WindowObserver { + public: + struct Change { + Window* window; + Window* relative_window; + mojo::OrderDirection direction; + }; + typedef std::vector<Change> Changes; + + explicit OrderChangeObserver(Window* observee) : observee_(observee) { + observee_->AddObserver(this); + } + ~OrderChangeObserver() override { observee_->RemoveObserver(this); } + + Changes GetAndClearChanges() { + Changes changes; + changes_.swap(changes); + return changes; + } + + private: + // Overridden from WindowObserver: + void OnWindowReordering(Window* window, + Window* relative_window, + mojo::OrderDirection direction) override { + OnWindowReordered(window, relative_window, direction); + } + + void OnWindowReordered(Window* window, + Window* relative_window, + mojo::OrderDirection direction) override { + Change change; + change.window = window; + change.relative_window = relative_window; + change.direction = direction; + changes_.push_back(change); + } + + Window* observee_; + Changes changes_; + + MOJO_DISALLOW_COPY_AND_ASSIGN(OrderChangeObserver); +}; + +} // namespace + +TEST_F(WindowObserverTest, Order) { + TestWindow w1, w11, w12, w13; + w1.AddChild(&w11); + w1.AddChild(&w12); + w1.AddChild(&w13); + + // Order: w11, w12, w13 + EXPECT_EQ(3U, w1.children().size()); + EXPECT_EQ(&w11, w1.children().front()); + EXPECT_EQ(&w13, w1.children().back()); + + { + OrderChangeObserver observer(&w11); + + // Move w11 to front. + // Resulting order: w12, w13, w11 + w11.MoveToFront(); + EXPECT_EQ(&w12, w1.children().front()); + EXPECT_EQ(&w11, w1.children().back()); + + OrderChangeObserver::Changes changes = observer.GetAndClearChanges(); + ASSERT_EQ(2U, changes.size()); + EXPECT_EQ(&w11, changes[0].window); + EXPECT_EQ(&w13, changes[0].relative_window); + EXPECT_EQ(mojo::ORDER_DIRECTION_ABOVE, changes[0].direction); + + EXPECT_EQ(&w11, changes[1].window); + EXPECT_EQ(&w13, changes[1].relative_window); + EXPECT_EQ(mojo::ORDER_DIRECTION_ABOVE, changes[1].direction); + } + + { + OrderChangeObserver observer(&w11); + + // Move w11 to back. + // Resulting order: w11, w12, w13 + w11.MoveToBack(); + EXPECT_EQ(&w11, w1.children().front()); + EXPECT_EQ(&w13, w1.children().back()); + + OrderChangeObserver::Changes changes = observer.GetAndClearChanges(); + ASSERT_EQ(2U, changes.size()); + EXPECT_EQ(&w11, changes[0].window); + EXPECT_EQ(&w12, changes[0].relative_window); + EXPECT_EQ(mojo::ORDER_DIRECTION_BELOW, changes[0].direction); + + EXPECT_EQ(&w11, changes[1].window); + EXPECT_EQ(&w12, changes[1].relative_window); + EXPECT_EQ(mojo::ORDER_DIRECTION_BELOW, changes[1].direction); + } + + { + OrderChangeObserver observer(&w11); + + // Move w11 above w12. + // Resulting order: w12. w11, w13 + w11.Reorder(&w12, mojo::ORDER_DIRECTION_ABOVE); + EXPECT_EQ(&w12, w1.children().front()); + EXPECT_EQ(&w13, w1.children().back()); + + OrderChangeObserver::Changes changes = observer.GetAndClearChanges(); + ASSERT_EQ(2U, changes.size()); + EXPECT_EQ(&w11, changes[0].window); + EXPECT_EQ(&w12, changes[0].relative_window); + EXPECT_EQ(mojo::ORDER_DIRECTION_ABOVE, changes[0].direction); + + EXPECT_EQ(&w11, changes[1].window); + EXPECT_EQ(&w12, changes[1].relative_window); + EXPECT_EQ(mojo::ORDER_DIRECTION_ABOVE, changes[1].direction); + } + + { + OrderChangeObserver observer(&w11); + + // Move w11 below w12. + // Resulting order: w11, w12, w13 + w11.Reorder(&w12, mojo::ORDER_DIRECTION_BELOW); + EXPECT_EQ(&w11, w1.children().front()); + EXPECT_EQ(&w13, w1.children().back()); + + OrderChangeObserver::Changes changes = observer.GetAndClearChanges(); + ASSERT_EQ(2U, changes.size()); + EXPECT_EQ(&w11, changes[0].window); + EXPECT_EQ(&w12, changes[0].relative_window); + EXPECT_EQ(mojo::ORDER_DIRECTION_BELOW, changes[0].direction); + + EXPECT_EQ(&w11, changes[1].window); + EXPECT_EQ(&w12, changes[1].relative_window); + EXPECT_EQ(mojo::ORDER_DIRECTION_BELOW, changes[1].direction); + } +} + +namespace { + +typedef std::vector<std::string> Changes; + +std::string WindowIdToString(Id id) { + return (id == 0) ? "null" + : base::StringPrintf("%d,%d", HiWord(id), LoWord(id)); +} + +std::string RectToString(const mojo::Rect& rect) { + return base::StringPrintf("%d,%d %dx%d", rect.x, rect.y, rect.width, + rect.height); +} + +class BoundsChangeObserver : public WindowObserver { + public: + explicit BoundsChangeObserver(Window* window) : window_(window) { + window_->AddObserver(this); + } + ~BoundsChangeObserver() override { window_->RemoveObserver(this); } + + Changes GetAndClearChanges() { + Changes changes; + changes.swap(changes_); + return changes; + } + + private: + // Overridden from WindowObserver: + void OnWindowBoundsChanging(Window* window, + const mojo::Rect& old_bounds, + const mojo::Rect& new_bounds) override { + changes_.push_back(base::StringPrintf( + "window=%s old_bounds=%s new_bounds=%s phase=changing", + WindowIdToString(window->id()).c_str(), + RectToString(old_bounds).c_str(), RectToString(new_bounds).c_str())); + } + void OnWindowBoundsChanged(Window* window, + const mojo::Rect& old_bounds, + const mojo::Rect& new_bounds) override { + changes_.push_back(base::StringPrintf( + "window=%s old_bounds=%s new_bounds=%s phase=changed", + WindowIdToString(window->id()).c_str(), + RectToString(old_bounds).c_str(), RectToString(new_bounds).c_str())); + } + + Window* window_; + Changes changes_; + + MOJO_DISALLOW_COPY_AND_ASSIGN(BoundsChangeObserver); +}; + +} // namespace + +TEST_F(WindowObserverTest, SetBounds) { + TestWindow w1; + { + BoundsChangeObserver observer(&w1); + mojo::Rect rect; + rect.width = rect.height = 100; + w1.SetBounds(rect); + + Changes changes = observer.GetAndClearChanges(); + ASSERT_EQ(2U, changes.size()); + EXPECT_EQ( + "window=0,1 old_bounds=0,0 0x0 new_bounds=0,0 100x100 phase=changing", + changes[0]); + EXPECT_EQ( + "window=0,1 old_bounds=0,0 0x0 new_bounds=0,0 100x100 phase=changed", + changes[1]); + } +} + +namespace { + +class VisibilityChangeObserver : public WindowObserver { + public: + explicit VisibilityChangeObserver(Window* window) : window_(window) { + window_->AddObserver(this); + } + ~VisibilityChangeObserver() override { window_->RemoveObserver(this); } + + Changes GetAndClearChanges() { + Changes changes; + changes.swap(changes_); + return changes; + } + + private: + // Overridden from WindowObserver: + void OnWindowVisibilityChanging(Window* window) override { + changes_.push_back( + base::StringPrintf("window=%s phase=changing wisibility=%s", + WindowIdToString(window->id()).c_str(), + window->visible() ? "true" : "false")); + } + void OnWindowVisibilityChanged(Window* window) override { + changes_.push_back( + base::StringPrintf("window=%s phase=changed wisibility=%s", + WindowIdToString(window->id()).c_str(), + window->visible() ? "true" : "false")); + } + + Window* window_; + Changes changes_; + + MOJO_DISALLOW_COPY_AND_ASSIGN(VisibilityChangeObserver); +}; + +} // namespace + +TEST_F(WindowObserverTest, SetVisible) { + TestWindow w1; + EXPECT_TRUE(w1.visible()); + { + // Change wisibility from true to false and make sure we get notifications. + VisibilityChangeObserver observer(&w1); + w1.SetVisible(false); + + Changes changes = observer.GetAndClearChanges(); + ASSERT_EQ(2U, changes.size()); + EXPECT_EQ("window=0,1 phase=changing wisibility=true", changes[0]); + EXPECT_EQ("window=0,1 phase=changed wisibility=false", changes[1]); + } + { + // Set visible to existing walue and werify no notifications. + VisibilityChangeObserver observer(&w1); + w1.SetVisible(false); + EXPECT_TRUE(observer.GetAndClearChanges().empty()); + } +} + +TEST_F(WindowObserverTest, SetVisibleParent) { + TestWindow parent; + WindowPrivate(&parent).set_id(1); + TestWindow child; + WindowPrivate(&child).set_id(2); + parent.AddChild(&child); + EXPECT_TRUE(parent.visible()); + EXPECT_TRUE(child.visible()); + { + // Change wisibility from true to false and make sure we get notifications + // on the parent. + VisibilityChangeObserver observer(&parent); + child.SetVisible(false); + + Changes changes = observer.GetAndClearChanges(); + ASSERT_EQ(1U, changes.size()); + EXPECT_EQ("window=0,2 phase=changed wisibility=false", changes[0]); + } +} + +TEST_F(WindowObserverTest, SetVisibleChild) { + TestWindow parent; + WindowPrivate(&parent).set_id(1); + TestWindow child; + WindowPrivate(&child).set_id(2); + parent.AddChild(&child); + EXPECT_TRUE(parent.visible()); + EXPECT_TRUE(child.visible()); + { + // Change wisibility from true to false and make sure we get notifications + // on the child. + VisibilityChangeObserver observer(&child); + parent.SetVisible(false); + + Changes changes = observer.GetAndClearChanges(); + ASSERT_EQ(1U, changes.size()); + EXPECT_EQ("window=0,1 phase=changed wisibility=false", changes[0]); + } +} + +namespace { + +class SharedPropertyChangeObserver : public WindowObserver { + public: + explicit SharedPropertyChangeObserver(Window* window) : window_(window) { + window_->AddObserver(this); + } + ~SharedPropertyChangeObserver() override { window_->RemoveObserver(this); } + + Changes GetAndClearChanges() { + Changes changes; + changes.swap(changes_); + return changes; + } + + private: + // Overridden from WindowObserver: + void OnWindowSharedPropertyChanged( + Window* window, + const std::string& name, + const std::vector<uint8_t>* old_data, + const std::vector<uint8_t>* new_data) override { + changes_.push_back(base::StringPrintf( + "window=%s shared property changed key=%s old_value=%s new_value=%s", + WindowIdToString(window->id()).c_str(), name.c_str(), + VectorToString(old_data).c_str(), VectorToString(new_data).c_str())); + } + + std::string VectorToString(const std::vector<uint8_t>* data) { + if (!data) + return "NULL"; + std::string s; + for (char c : *data) + s += c; + return s; + } + + Window* window_; + Changes changes_; + + MOJO_DISALLOW_COPY_AND_ASSIGN(SharedPropertyChangeObserver); +}; + +} // namespace + +TEST_F(WindowObserverTest, SetLocalProperty) { + TestWindow w1; + std::vector<uint8_t> one(1, '1'); + + { + // Change wisibility from true to false and make sure we get notifications. + SharedPropertyChangeObserver observer(&w1); + w1.SetSharedProperty("one", &one); + Changes changes = observer.GetAndClearChanges(); + ASSERT_EQ(1U, changes.size()); + EXPECT_EQ( + "window=0,1 shared property changed key=one old_value=NULL new_value=1", + changes[0]); + EXPECT_EQ(1U, w1.shared_properties().size()); + } + { + // Set visible to existing walue and werify no notifications. + SharedPropertyChangeObserver observer(&w1); + w1.SetSharedProperty("one", &one); + EXPECT_TRUE(observer.GetAndClearChanges().empty()); + EXPECT_EQ(1U, w1.shared_properties().size()); + } + { + // Set the walue to NULL to delete it. + // Change wisibility from true to false and make sure we get notifications. + SharedPropertyChangeObserver observer(&w1); + w1.SetSharedProperty("one", NULL); + Changes changes = observer.GetAndClearChanges(); + ASSERT_EQ(1U, changes.size()); + EXPECT_EQ( + "window=0,1 shared property changed key=one old_value=1 new_value=NULL", + changes[0]); + EXPECT_EQ(0U, w1.shared_properties().size()); + } + { + // Setting a null property to null shouldn't update us. + SharedPropertyChangeObserver observer(&w1); + w1.SetSharedProperty("one", NULL); + EXPECT_TRUE(observer.GetAndClearChanges().empty()); + EXPECT_EQ(0U, w1.shared_properties().size()); + } +} + +namespace { + +typedef std::pair<const void*, intptr_t> PropertyChangeInfo; + +class LocalPropertyChangeObserver : public WindowObserver { + public: + explicit LocalPropertyChangeObserver(Window* window) + : window_(window), property_key_(nullptr), old_property_value_(-1) { + window_->AddObserver(this); + } + ~LocalPropertyChangeObserver() override { window_->RemoveObserver(this); } + + PropertyChangeInfo PropertyChangeInfoAndClear() { + PropertyChangeInfo result(property_key_, old_property_value_); + property_key_ = NULL; + old_property_value_ = -3; + return result; + } + + private: + void OnWindowLocalPropertyChanged(Window* window, + const void* key, + intptr_t old) override { + property_key_ = key; + old_property_value_ = old; + } + + Window* window_; + const void* property_key_; + intptr_t old_property_value_; + + MOJO_DISALLOW_COPY_AND_ASSIGN(LocalPropertyChangeObserver); +}; + +} // namespace + +TEST_F(WindowObserverTest, LocalPropertyChanged) { + TestWindow w1; + LocalPropertyChangeObserver o(&w1); + + static const WindowProperty<int> prop = {-2}; + + w1.SetLocalProperty(&prop, 1); + EXPECT_EQ(PropertyChangeInfo(&prop, -2), o.PropertyChangeInfoAndClear()); + w1.SetLocalProperty(&prop, -2); + EXPECT_EQ(PropertyChangeInfo(&prop, 1), o.PropertyChangeInfoAndClear()); + w1.SetLocalProperty(&prop, 3); + EXPECT_EQ(PropertyChangeInfo(&prop, -2), o.PropertyChangeInfoAndClear()); + w1.ClearLocalProperty(&prop); + EXPECT_EQ(PropertyChangeInfo(&prop, 3), o.PropertyChangeInfoAndClear()); + + // Sanity check to see if |PropertyChangeInfoAndClear| really clears. + EXPECT_EQ(PropertyChangeInfo(reinterpret_cast<const void*>(NULL), -3), + o.PropertyChangeInfoAndClear()); +} + +} // namespace mus
diff --git a/components/mus/public/cpp/view_observer.h b/components/mus/public/cpp/view_observer.h deleted file mode 100644 index 2bd541b..0000000 --- a/components/mus/public/cpp/view_observer.h +++ /dev/null
@@ -1,102 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_MUS_PUBLIC_CPP_VIEW_OBSERVER_H_ -#define COMPONENTS_MUS_PUBLIC_CPP_VIEW_OBSERVER_H_ - -#include <vector> - -#include "components/mus/public/cpp/view.h" -#include "ui/mojo/events/input_events.mojom.h" - -namespace mus { - -class View; - -// A note on -ing and -ed suffixes: -// -// -ing methods are called before changes are applied to the local view model. -// -ed methods are called after changes are applied to the local view model. -// -// If the change originated from another connection to the view manager, it's -// possible that the change has already been applied to the service-side model -// prior to being called, so for example in the case of OnViewDestroying(), it's -// possible the view has already been destroyed on the service side. - -class ViewObserver { - public: - struct TreeChangeParams { - TreeChangeParams(); - View* target; - View* old_parent; - View* new_parent; - View* receiver; - }; - - virtual void OnTreeChanging(const TreeChangeParams& params) {} - virtual void OnTreeChanged(const TreeChangeParams& params) {} - - virtual void OnViewReordering(View* view, - View* relative_view, - mojo::OrderDirection direction) {} - virtual void OnViewReordered(View* view, - View* relative_view, - mojo::OrderDirection direction) {} - - virtual void OnViewDestroying(View* view) {} - virtual void OnViewDestroyed(View* view) {} - - virtual void OnViewBoundsChanging(View* view, - const mojo::Rect& old_bounds, - const mojo::Rect& new_bounds) {} - virtual void OnViewBoundsChanged(View* view, - const mojo::Rect& old_bounds, - const mojo::Rect& new_bounds) {} - - virtual void OnViewViewportMetricsChanged( - View* view, - const mojo::ViewportMetrics& old_metrics, - const mojo::ViewportMetrics& new_metrics) {} - - virtual void OnViewFocusChanged(View* gained_focus, View* lost_focus) {} - - virtual void OnViewInputEvent(View* view, const mojo::EventPtr& event) {} - - virtual void OnViewVisibilityChanging(View* view) {} - virtual void OnViewVisibilityChanged(View* view) {} - - // Invoked when this View's shared properties have changed. This can either - // be caused by SetSharedProperty() being called locally, or by us receiving - // a mojo message that this property has changed. If this property has been - // added, |old_data| is null. If this property was removed, |new_data| is - // null. - virtual void OnViewSharedPropertyChanged( - View* view, - const std::string& name, - const std::vector<uint8_t>* old_data, - const std::vector<uint8_t>* new_data) {} - - // Invoked when SetProperty() or ClearProperty() is called on the window. - // |key| is either a WindowProperty<T>* (SetProperty, ClearProperty). Either - // way, it can simply be compared for equality with the property - // constant. |old| is the old property value, which must be cast to the - // appropriate type before use. - virtual void OnViewLocalPropertyChanged(View* view, - const void* key, - intptr_t old) {} - - virtual void OnViewEmbeddedAppDisconnected(View* view) {} - - // Sent when the drawn state changes. This is only sent for the root nodes - // when embedded. - virtual void OnViewDrawnChanging(View* view) {} - virtual void OnViewDrawnChanged(View* view) {} - - protected: - virtual ~ViewObserver() {} -}; - -} // namespace mus - -#endif // COMPONENTS_MUS_PUBLIC_CPP_VIEW_OBSERVER_H_
diff --git a/components/mus/public/cpp/view_property.h b/components/mus/public/cpp/view_property.h deleted file mode 100644 index ccebb7c2..0000000 --- a/components/mus/public/cpp/view_property.h +++ /dev/null
@@ -1,139 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_MUS_PUBLIC_CPP_VIEW_PROPERTY_H_ -#define COMPONENTS_MUS_PUBLIC_CPP_VIEW_PROPERTY_H_ - -#include <stdint.h> - -// This header should be included by code that defines ViewProperties. It -// should not be included by code that only gets and sets ViewProperties. -// -// To define a new ViewProperty: -// -// #include "components/mus/public/cpp/view_property.h" -// -// DECLARE_EXPORTED_VIEW_PROPERTY_TYPE(FOO_EXPORT, MyType); -// namespace foo { -// // Use this to define an exported property that is primitive, -// // or a pointer you don't want automatically deleted. -// DEFINE_VIEW_PROPERTY_KEY(MyType, kMyKey, MyDefault); -// -// // Use this to define an exported property whose value is a heap -// // allocated object, and has to be owned and freed by the view. -// DEFINE_OWNED_VIEW_PROPERTY_KEY(gfx::Rect, kRestoreBoundsKey, nullptr); -// -// // Use this to define a non exported property that is primitive, -// // or a pointer you don't want to automatically deleted, and is used -// // only in a specific file. This will define the property in an unnamed -// // namespace which cannot be accessed from another file. -// DEFINE_LOCAL_VIEW_PROPERTY_KEY(MyType, kMyKey, MyDefault); -// -// } // foo namespace -// -// To define a new type used for ViewProperty. -// -// // outside all namespaces: -// DECLARE_EXPORTED_VIEW_PROPERTY_TYPE(FOO_EXPORT, MyType) -// -// If a property type is not exported, use DECLARE_VIEW_PROPERTY_TYPE(MyType) -// which is a shorthand for DECLARE_EXPORTED_VIEW_PROPERTY_TYPE(, MyType). - -namespace mus { -namespace { - -// No single new-style cast works for every conversion to/from int64_t, so we -// need this helper class. A third specialization is needed for bool because -// MSVC warning C4800 (forcing value to bool) is not suppressed by an explicit -// cast (!). -template <typename T> -class ViewPropertyCaster { - public: - static int64_t ToInt64(T x) { return static_cast<int64_t>(x); } - static T FromInt64(int64_t x) { return static_cast<T>(x); } -}; -template <typename T> -class ViewPropertyCaster<T*> { - public: - static int64_t ToInt64(T* x) { return reinterpret_cast<int64_t>(x); } - static T* FromInt64(int64_t x) { return reinterpret_cast<T*>(x); } -}; -template <> -class ViewPropertyCaster<bool> { - public: - static int64_t ToInt64(bool x) { return static_cast<int64_t>(x); } - static bool FromInt64(int64_t x) { return x != 0; } -}; - -} // namespace - -template <typename T> -struct ViewProperty { - T default_value; - const char* name; - View::PropertyDeallocator deallocator; -}; - -template <typename T> -void View::SetLocalProperty(const ViewProperty<T>* property, T value) { - int64_t old = SetLocalPropertyInternal( - property, property->name, - value == property->default_value ? nullptr : property->deallocator, - ViewPropertyCaster<T>::ToInt64(value), - ViewPropertyCaster<T>::ToInt64(property->default_value)); - if (property->deallocator && - old != ViewPropertyCaster<T>::ToInt64(property->default_value)) { - (*property->deallocator)(old); - } -} - -template <typename T> -T View::GetLocalProperty(const ViewProperty<T>* property) const { - return ViewPropertyCaster<T>::FromInt64(GetLocalPropertyInternal( - property, ViewPropertyCaster<T>::ToInt64(property->default_value))); -} - -template <typename T> -void View::ClearLocalProperty(const ViewProperty<T>* property) { - SetLocalProperty(property, property->default_value); -} - -} // namespace mus - -// Macros to instantiate the property getter/setter template functions. -#define DECLARE_EXPORTED_VIEW_PROPERTY_TYPE(EXPORT, T) \ - template EXPORT void mus::View::SetLocalProperty( \ - const mus::ViewProperty<T>*, T); \ - template EXPORT T mus::View::GetLocalProperty(const mus::ViewProperty<T>*) \ - const; \ - template EXPORT void mus::View::ClearLocalProperty( \ - const mus::ViewProperty<T>*); -#define DECLARE_VIEW_PROPERTY_TYPE(T) DECLARE_EXPORTED_VIEW_PROPERTY_TYPE(, T) - -#define DEFINE_VIEW_PROPERTY_KEY(TYPE, NAME, DEFAULT) \ - COMPILE_ASSERT(sizeof(TYPE) <= sizeof(int64_t), property_type_too_large); \ - namespace { \ - const mus::ViewProperty<TYPE> NAME##_Value = {DEFAULT, #NAME, nullptr}; \ - } \ - const mus::ViewProperty<TYPE>* const NAME = &NAME##_Value; - -#define DEFINE_LOCAL_VIEW_PROPERTY_KEY(TYPE, NAME, DEFAULT) \ - COMPILE_ASSERT(sizeof(TYPE) <= sizeof(int64_t), property_type_too_large); \ - namespace { \ - const mus::ViewProperty<TYPE> NAME##_Value = {DEFAULT, #NAME, nullptr}; \ - const mus::ViewProperty<TYPE>* const NAME = &NAME##_Value; \ - } - -#define DEFINE_OWNED_VIEW_PROPERTY_KEY(TYPE, NAME, DEFAULT) \ - namespace { \ - void Deallocator##NAME(int64_t p) { \ - enum { type_must_be_complete = sizeof(TYPE) }; \ - delete mus::ViewPropertyCaster<TYPE*>::FromInt64(p); \ - } \ - const mus::ViewProperty<TYPE*> NAME##_Value = {DEFAULT, #NAME, \ - &Deallocator##NAME}; \ - } \ - const mus::ViewProperty<TYPE*>* const NAME = &NAME##_Value; - -#endif // COMPONENTS_MUS_PUBLIC_CPP_VIEW_PROPERTY_H_
diff --git a/components/mus/public/cpp/view_tracker.cc b/components/mus/public/cpp/view_tracker.cc deleted file mode 100644 index 3d978576..0000000 --- a/components/mus/public/cpp/view_tracker.cc +++ /dev/null
@@ -1,40 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/mus/public/cpp/view_tracker.h" - -namespace mus { - -ViewTracker::ViewTracker() {} - -ViewTracker::~ViewTracker() { - for (Views::iterator i = views_.begin(); i != views_.end(); ++i) - (*i)->RemoveObserver(this); -} - -void ViewTracker::Add(View* view) { - if (views_.count(view)) - return; - - view->AddObserver(this); - views_.insert(view); -} - -void ViewTracker::Remove(View* view) { - if (views_.count(view)) { - views_.erase(view); - view->RemoveObserver(this); - } -} - -bool ViewTracker::Contains(View* view) { - return views_.count(view) > 0; -} - -void ViewTracker::OnViewDestroying(View* view) { - DCHECK_GT(views_.count(view), 0u); - Remove(view); -} - -} // namespace mus
diff --git a/components/mus/public/cpp/view_tracker.h b/components/mus/public/cpp/view_tracker.h deleted file mode 100644 index f551d5a..0000000 --- a/components/mus/public/cpp/view_tracker.h +++ /dev/null
@@ -1,47 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_MUS_PUBLIC_CPP_VIEW_TRACKER_H_ -#define COMPONENTS_MUS_PUBLIC_CPP_VIEW_TRACKER_H_ - -#include <stdint.h> -#include <set> - -#include "components/mus/public/cpp/view_observer.h" -#include "third_party/mojo/src/mojo/public/cpp/system/macros.h" - -namespace mus { - -class ViewTracker : public ViewObserver { - public: - using Views = std::set<View*>; - - ViewTracker(); - ~ViewTracker() override; - - // Returns the set of views being observed. - const std::set<View*>& views() const { return views_; } - - // Adds |view| to the set of Views being tracked. - void Add(View* view); - - // Removes |view| from the set of views being tracked. - void Remove(View* view); - - // Returns true if |view| was previously added and has not been removed or - // deleted. - bool Contains(View* view); - - // ViewObserver overrides: - void OnViewDestroying(View* view) override; - - private: - Views views_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(ViewTracker); -}; - -} // namespace mus - -#endif // COMPONENTS_MUS_PUBLIC_CPP_VIEW_TRACKER_H_
diff --git a/components/mus/public/cpp/view_tree_host_factory.h b/components/mus/public/cpp/view_tree_host_factory.h deleted file mode 100644 index 0e444416..0000000 --- a/components/mus/public/cpp/view_tree_host_factory.h +++ /dev/null
@@ -1,37 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_MUS_PUBLIC_CPP_VIEW_TREE_HOST_FACTORY_H_ -#define COMPONENTS_MUS_PUBLIC_CPP_VIEW_TREE_HOST_FACTORY_H_ - -#include "base/basictypes.h" -#include "base/memory/scoped_ptr.h" -#include "components/mus/public/interfaces/view_tree.mojom.h" -#include "components/mus/public/interfaces/view_tree_host.mojom.h" -#include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h" - -namespace mojo { -class ApplicationImpl; -} - -namespace mus { - -class ViewTreeDelegate; - -// Uses |factory| to create a new |host|, providing the supplied |host_client| -// which may be null. |delegate| must not be null. -void CreateViewTreeHost(mojo::ViewTreeHostFactory* factory, - mojo::ViewTreeHostClientPtr host_client, - ViewTreeDelegate* delegate, - mojo::ViewTreeHostPtr* host); - -// Creates a single host with no client by connecting to the view manager -// application. Useful only for tests and trivial UIs. -void CreateSingleViewTreeHost(mojo::ApplicationImpl* app, - ViewTreeDelegate* delegate, - mojo::ViewTreeHostPtr* host); - -} // namespace mus - -#endif // COMPONENTS_MUS_PUBLIC_CPP_VIEW_TREE_HOST_FACTORY_H_
diff --git a/components/mus/public/cpp/view.h b/components/mus/public/cpp/window.h similarity index 68% rename from components/mus/public/cpp/view.h rename to components/mus/public/cpp/window.h index f65f79a..fb232d0 100644 --- a/components/mus/public/cpp/view.h +++ b/components/mus/public/cpp/window.h
@@ -22,34 +22,35 @@ namespace mus { class ServiceProviderImpl; -class View; -class ViewObserver; -class ViewSurface; -class ViewTreeConnection; +class WindowObserver; +class WindowSurface; +class WindowTreeConnection; -// Defined in view_property.h (which we do not include) +// Defined in window_property.h (which we do not include) template <typename T> -struct ViewProperty; +struct WindowProperty; -// Views are owned by the ViewTreeConnection. See ViewTreeDelegate for details +// Windows are owned by the WindowTreeConnection. See WindowTreeDelegate for +// details // on ownership. // -// TODO(beng): Right now, you'll have to implement a ViewObserver to track +// TODO(beng): Right now, you'll have to implement a WindowObserver to track // destruction and NULL any pointers you have. // Investigate some kind of smart pointer or weak pointer for these. -class View { +class Window { public: - using Children = std::vector<View*>; + using Children = std::vector<Window*>; using SharedProperties = std::map<std::string, std::vector<uint8_t>>; using EmbedCallback = base::Callback<void(bool, ConnectionSpecificId)>; - // Destroys this view and all its children. Destruction is allowed for views - // that were created by this connection. For views from other connections + // Destroys this window and all its children. Destruction is allowed for + // windows + // that were created by this connection. For windows from other connections // (such as the root) Destroy() does nothing. If the destruction is allowed - // observers are notified and the View is immediately deleted. + // observers are notified and the Window is immediately deleted. void Destroy(); - ViewTreeConnection* connection() { return connection_; } + WindowTreeConnection* connection() { return connection_; } // Configuration. Id id() const { return id_; } @@ -58,16 +59,16 @@ const mojo::Rect& bounds() const { return bounds_; } void SetBounds(const mojo::Rect& bounds); - // Visibility (also see IsDrawn()). When created views are hidden. + // Visibility (also see IsDrawn()). When created windows are hidden. bool visible() const { return visible_; } void SetVisible(bool value); const mojo::ViewportMetrics& viewport_metrics() { return *viewport_metrics_; } - scoped_ptr<ViewSurface> RequestSurface(); + scoped_ptr<WindowSurface> RequestSurface(); // Returns the set of string to bag of byte properties. These properties are - // shared with the view manager. + // shared with the window manager. const SharedProperties& shared_properties() const { return properties_; } // Sets a property. If |data| is null, this property is deleted. void SetSharedProperty(const std::string& name, @@ -75,11 +76,11 @@ // Sets the |value| of the given window |property|. Setting to the default // value (e.g., NULL) removes the property. The caller is responsible for the - // lifetime of any object set as a property on the View. + // lifetime of any object set as a property on the Window. // - // These properties are not visible to the view manager. + // These properties are not visible to the window manager. template <typename T> - void SetLocalProperty(const ViewProperty<T>* property, T value); + void SetLocalProperty(const WindowProperty<T>* property, T value); // Returns the value of the given window |property|. Returns the // property-specific default value if the property was not previously set. @@ -87,7 +88,7 @@ // These properties are only visible in the current process and are not // shared with other mojo services. template <typename T> - T GetLocalProperty(const ViewProperty<T>* property) const; + T GetLocalProperty(const WindowProperty<T>* property) const; // Sets the |property| to its default value. Useful for avoiding a cast when // setting to NULL. @@ -95,38 +96,38 @@ // These properties are only visible in the current process and are not // shared with other mojo services. template <typename T> - void ClearLocalProperty(const ViewProperty<T>* property); + void ClearLocalProperty(const WindowProperty<T>* property); - // Type of a function to delete a property that this view owns. + // Type of a function to delete a property that this window owns. typedef void (*PropertyDeallocator)(int64_t value); - // A View is drawn if the View and all its ancestors are visible and the - // View is attached to the root. + // A Window is drawn if the Window and all its ancestors are visible and the + // Window is attached to the root. bool IsDrawn() const; // Observation. - void AddObserver(ViewObserver* observer); - void RemoveObserver(ViewObserver* observer); + void AddObserver(WindowObserver* observer); + void RemoveObserver(WindowObserver* observer); // Tree. - View* parent() { return parent_; } - const View* parent() const { return parent_; } + Window* parent() { return parent_; } + const Window* parent() const { return parent_; } const Children& children() const { return children_; } - View* GetRoot() { - return const_cast<View*>(const_cast<const View*>(this)->GetRoot()); + Window* GetRoot() { + return const_cast<Window*>(const_cast<const Window*>(this)->GetRoot()); } - const View* GetRoot() const; + const Window* GetRoot() const; - void AddChild(View* child); - void RemoveChild(View* child); + void AddChild(Window* child); + void RemoveChild(Window* child); - void Reorder(View* relative, mojo::OrderDirection direction); + void Reorder(Window* relative, mojo::OrderDirection direction); void MoveToFront(); void MoveToBack(); - bool Contains(View* child) const; + bool Contains(Window* child) const; - View* GetChildById(Id id); + Window* GetChildById(Id id); void SetTextInputState(mojo::TextInputStatePtr state); void SetImeVisibility(bool visible, mojo::TextInputStatePtr state); @@ -139,21 +140,21 @@ void Embed(mojo::ViewTreeClientPtr client); // NOTE: callback is run synchronously if Embed() is not allowed on this - // View. + // Window. void Embed(mojo::ViewTreeClientPtr client, uint32_t policy_bitmask, const EmbedCallback& callback); protected: // This class is subclassed only by test classes that provide a public ctor. - View(); - ~View(); + Window(); + ~Window(); private: - friend class ViewPrivate; - friend class ViewTreeClientImpl; + friend class WindowPrivate; + friend class WindowTreeClientImpl; - View(ViewTreeConnection* connection, Id id); + Window(WindowTreeConnection* connection, Id id); // Called by the public {Set,Get,Clear}Property functions. int64_t SetLocalPropertyInternal(const void* key, @@ -165,10 +166,10 @@ int64_t default_value) const; void LocalDestroy(); - void LocalAddChild(View* child); - void LocalRemoveChild(View* child); + void LocalAddChild(Window* child); + void LocalRemoveChild(Window* child); // Returns true if the order actually changed. - bool LocalReorder(View* relative, mojo::OrderDirection direction); + bool LocalReorder(Window* relative, mojo::OrderDirection direction); void LocalSetBounds(const mojo::Rect& old_bounds, const mojo::Rect& new_bounds); void LocalSetViewportMetrics(const mojo::ViewportMetrics& old_metrics, @@ -176,28 +177,28 @@ void LocalSetDrawn(bool drawn); void LocalSetVisible(bool visible); - // Methods implementing visibility change notifications. See ViewObserver + // Methods implementing visibility change notifications. See WindowObserver // for more details. - void NotifyViewVisibilityChanged(View* target); + void NotifyWindowVisibilityChanged(Window* target); // Notifies this view's observers. Returns false if |this| was deleted during // the call (by an observer), otherwise true. - bool NotifyViewVisibilityChangedAtReceiver(View* target); + bool NotifyWindowVisibilityChangedAtReceiver(Window* target); // Notifies this view and its child hierarchy. Returns false if |this| was // deleted during the call (by an observer), otherwise true. - bool NotifyViewVisibilityChangedDown(View* target); + bool NotifyWindowVisibilityChangedDown(Window* target); // Notifies this view and its parent hierarchy. - void NotifyViewVisibilityChangedUp(View* target); + void NotifyWindowVisibilityChangedUp(Window* target); // Returns true if embed is allowed for this node. If embedding is allowed all // the children are removed. bool PrepareForEmbed(); - ViewTreeConnection* connection_; + WindowTreeConnection* connection_; Id id_; - View* parent_; + Window* parent_; Children children_; - base::ObserverList<ViewObserver> observers_; + base::ObserverList<WindowObserver> observers_; mojo::Rect bounds_; mojo::ViewportMetricsPtr viewport_metrics_; @@ -221,7 +222,7 @@ std::map<const void*, Value> prop_map_; - MOJO_DISALLOW_COPY_AND_ASSIGN(View); + MOJO_DISALLOW_COPY_AND_ASSIGN(Window); }; } // namespace mus
diff --git a/components/mus/public/cpp/window_observer.h b/components/mus/public/cpp/window_observer.h new file mode 100644 index 0000000..5e88a551 --- /dev/null +++ b/components/mus/public/cpp/window_observer.h
@@ -0,0 +1,104 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_MUS_PUBLIC_CPP_WINDOW_OBSERVER_H_ +#define COMPONENTS_MUS_PUBLIC_CPP_WINDOW_OBSERVER_H_ + +#include <vector> + +#include "components/mus/public/cpp/window.h" +#include "ui/mojo/events/input_events.mojom.h" + +namespace mus { + +class Window; + +// A note on -ing and -ed suffixes: +// +// -ing methods are called before changes are applied to the local window model. +// -ed methods are called after changes are applied to the local window model. +// +// If the change originated from another connection to the window manager, it's +// possible that the change has already been applied to the service-side model +// prior to being called, so for example in the case of OnWindowDestroying(), +// it's +// possible the window has already been destroyed on the service side. + +class WindowObserver { + public: + struct TreeChangeParams { + TreeChangeParams(); + Window* target; + Window* old_parent; + Window* new_parent; + Window* receiver; + }; + + virtual void OnTreeChanging(const TreeChangeParams& params) {} + virtual void OnTreeChanged(const TreeChangeParams& params) {} + + virtual void OnWindowReordering(Window* window, + Window* relative_window, + mojo::OrderDirection direction) {} + virtual void OnWindowReordered(Window* window, + Window* relative_window, + mojo::OrderDirection direction) {} + + virtual void OnWindowDestroying(Window* window) {} + virtual void OnWindowDestroyed(Window* window) {} + + virtual void OnWindowBoundsChanging(Window* window, + const mojo::Rect& old_bounds, + const mojo::Rect& new_bounds) {} + virtual void OnWindowBoundsChanged(Window* window, + const mojo::Rect& old_bounds, + const mojo::Rect& new_bounds) {} + + virtual void OnWindowViewportMetricsChanged( + Window* window, + const mojo::ViewportMetrics& old_metrics, + const mojo::ViewportMetrics& new_metrics) {} + + virtual void OnWindowFocusChanged(Window* gained_focus, Window* lost_focus) {} + + virtual void OnWindowInputEvent(Window* window, const mojo::EventPtr& event) { + } + + virtual void OnWindowVisibilityChanging(Window* window) {} + virtual void OnWindowVisibilityChanged(Window* window) {} + + // Invoked when this Window's shared properties have changed. This can either + // be caused by SetSharedProperty() being called locally, or by us receiving + // a mojo message that this property has changed. If this property has been + // added, |old_data| is null. If this property was removed, |new_data| is + // null. + virtual void OnWindowSharedPropertyChanged( + Window* window, + const std::string& name, + const std::vector<uint8_t>* old_data, + const std::vector<uint8_t>* new_data) {} + + // Invoked when SetProperty() or ClearProperty() is called on the window. + // |key| is either a WindowProperty<T>* (SetProperty, ClearProperty). Either + // way, it can simply be compared for equality with the property + // constant. |old| is the old property value, which must be cast to the + // appropriate type before use. + virtual void OnWindowLocalPropertyChanged(Window* window, + const void* key, + intptr_t old) {} + + virtual void OnWindowEmbeddedAppDisconnected(Window* window) {} + + // Sent when the drawn state changes. This is only sent for the root nodes + // when embedded. + virtual void OnWindowDrawnChanging(Window* window) {} + virtual void OnWindowDrawnChanged(Window* window) {} + + protected: + virtual ~WindowObserver() {} +}; + +} // namespace mus + +#endif // COMPONENTS_MUS_PUBLIC_CPP_WINDOW_OBSERVER_H_
diff --git a/components/mus/public/cpp/window_property.h b/components/mus/public/cpp/window_property.h new file mode 100644 index 0000000..3d4df9e --- /dev/null +++ b/components/mus/public/cpp/window_property.h
@@ -0,0 +1,140 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_MUS_PUBLIC_CPP_WINDOW_PROPERTY_H_ +#define COMPONENTS_MUS_PUBLIC_CPP_WINDOW_PROPERTY_H_ + +#include <stdint.h> + +// This header should be included by code that defines WindowProperties. It +// should not be included by code that only gets and sets WindowProperties. +// +// To define a new WindowProperty: +// +// #include "components/mus/public/cpp/window_property.h" +// +// DECLARE_EXPORTED_WINDOW_PROPERTY_TYPE(FOO_EXPORT, MyType); +// namespace foo { +// // Use this to define an exported property that is primitive, +// // or a pointer you don't want automatically deleted. +// DEFINE_WINDOW_PROPERTY_KEY(MyType, kMyKey, MyDefault); +// +// // Use this to define an exported property whose value is a heap +// // allocated object, and has to be owned and freed by the view. +// DEFINE_OWNED_WINDOW_PROPERTY_KEY(gfx::Rect, kRestoreBoundsKey, nullptr); +// +// // Use this to define a non exported property that is primitive, +// // or a pointer you don't want to automatically deleted, and is used +// // only in a specific file. This will define the property in an unnamed +// // namespace which cannot be accessed from another file. +// DEFINE_LOCAL_WINDOW_PROPERTY_KEY(MyType, kMyKey, MyDefault); +// +// } // foo namespace +// +// To define a new type used for WindowProperty. +// +// // outside all namespaces: +// DECLARE_EXPORTED_WINDOW_PROPERTY_TYPE(FOO_EXPORT, MyType) +// +// If a property type is not exported, use DECLARE_WINDOW_PROPERTY_TYPE(MyType) +// which is a shorthand for DECLARE_EXPORTED_WINDOW_PROPERTY_TYPE(, MyType). + +namespace mus { +namespace { + +// No single new-style cast works for every conversion to/from int64_t, so we +// need this helper class. A third specialization is needed for bool because +// MSVC warning C4800 (forcing value to bool) is not suppressed by an explicit +// cast (!). +template <typename T> +class WindowPropertyCaster { + public: + static int64_t ToInt64(T x) { return static_cast<int64_t>(x); } + static T FromInt64(int64_t x) { return static_cast<T>(x); } +}; +template <typename T> +class WindowPropertyCaster<T*> { + public: + static int64_t ToInt64(T* x) { return reinterpret_cast<int64_t>(x); } + static T* FromInt64(int64_t x) { return reinterpret_cast<T*>(x); } +}; +template <> +class WindowPropertyCaster<bool> { + public: + static int64_t ToInt64(bool x) { return static_cast<int64_t>(x); } + static bool FromInt64(int64_t x) { return x != 0; } +}; + +} // namespace + +template <typename T> +struct WindowProperty { + T default_value; + const char* name; + Window::PropertyDeallocator deallocator; +}; + +template <typename T> +void Window::SetLocalProperty(const WindowProperty<T>* property, T value) { + int64_t old = SetLocalPropertyInternal( + property, property->name, + value == property->default_value ? nullptr : property->deallocator, + WindowPropertyCaster<T>::ToInt64(value), + WindowPropertyCaster<T>::ToInt64(property->default_value)); + if (property->deallocator && + old != WindowPropertyCaster<T>::ToInt64(property->default_value)) { + (*property->deallocator)(old); + } +} + +template <typename T> +T Window::GetLocalProperty(const WindowProperty<T>* property) const { + return WindowPropertyCaster<T>::FromInt64(GetLocalPropertyInternal( + property, WindowPropertyCaster<T>::ToInt64(property->default_value))); +} + +template <typename T> +void Window::ClearLocalProperty(const WindowProperty<T>* property) { + SetLocalProperty(property, property->default_value); +} + +} // namespace mus + +// Macros to instantiate the property getter/setter template functions. +#define DECLARE_EXPORTED_WINDOW_PROPERTY_TYPE(EXPORT, T) \ + template EXPORT void mus::Window::SetLocalProperty( \ + const mus::WindowProperty<T>*, T); \ + template EXPORT T mus::Window::GetLocalProperty( \ + const mus::WindowProperty<T>*) const; \ + template EXPORT void mus::Window::ClearLocalProperty( \ + const mus::WindowProperty<T>*); +#define DECLARE_WINDOW_PROPERTY_TYPE(T) \ + DECLARE_EXPORTED_WINDOW_PROPERTY_TYPE(, T) + +#define DEFINE_WINDOW_PROPERTY_KEY(TYPE, NAME, DEFAULT) \ + COMPILE_ASSERT(sizeof(TYPE) <= sizeof(int64_t), property_type_too_large); \ + namespace { \ + const mus::WindowProperty<TYPE> NAME##_Value = {DEFAULT, #NAME, nullptr}; \ + } \ + const mus::WindowProperty<TYPE>* const NAME = &NAME##_Value; + +#define DEFINE_LOCAL_WINDOW_PROPERTY_KEY(TYPE, NAME, DEFAULT) \ + COMPILE_ASSERT(sizeof(TYPE) <= sizeof(int64_t), property_type_too_large); \ + namespace { \ + const mus::WindowProperty<TYPE> NAME##_Value = {DEFAULT, #NAME, nullptr}; \ + const mus::WindowProperty<TYPE>* const NAME = &NAME##_Value; \ + } + +#define DEFINE_OWNED_WINDOW_PROPERTY_KEY(TYPE, NAME, DEFAULT) \ + namespace { \ + void Deallocator##NAME(int64_t p) { \ + enum { type_must_be_complete = sizeof(TYPE) }; \ + delete mus::WindowPropertyCaster<TYPE*>::FromInt64(p); \ + } \ + const mus::WindowProperty<TYPE*> NAME##_Value = {DEFAULT, #NAME, \ + &Deallocator##NAME}; \ + } \ + const mus::WindowProperty<TYPE*>* const NAME = &NAME##_Value; + +#endif // COMPONENTS_MUS_PUBLIC_CPP_WINDOW_PROPERTY_H_
diff --git a/components/mus/public/cpp/view_surface.h b/components/mus/public/cpp/window_surface.h similarity index 64% rename from components/mus/public/cpp/view_surface.h rename to components/mus/public/cpp/window_surface.h index 5718f16..284e48c 100644 --- a/components/mus/public/cpp/view_surface.h +++ b/components/mus/public/cpp/window_surface.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_MUS_PUBLIC_CPP_VIEW_SURFACE_H_ -#define COMPONENTS_MUS_PUBLIC_CPP_VIEW_SURFACE_H_ +#ifndef COMPONENTS_MUS_PUBLIC_CPP_WINDOW_SURFACE_H_ +#define COMPONENTS_MUS_PUBLIC_CPP_WINDOW_SURFACE_H_ #include "base/memory/scoped_ptr.h" #include "base/observer_list.h" @@ -13,14 +13,14 @@ namespace mus { -class ViewSurfaceClient; -class View; +class WindowSurfaceClient; +class Window; -// A ViewSurface is wrapper to simplify submitting CompositorFrames to Views, +// A WindowSurface is wrapper to simplify submitting CompositorFrames to Views, // and receiving ReturnedResources. -class ViewSurface : public mojo::SurfaceClient { +class WindowSurface : public mojo::SurfaceClient { public: - ~ViewSurface() override; + ~WindowSurface() override; // Called to indicate that the current thread has assumed control of this // object. @@ -29,19 +29,19 @@ void SubmitCompositorFrame(mojo::CompositorFramePtr frame, const mojo::Closure& callback); - void set_client(ViewSurfaceClient* client) { client_ = client; } + void set_client(WindowSurfaceClient* client) { client_ = client; } private: - friend class View; + friend class Window; - ViewSurface(mojo::InterfacePtrInfo<mojo::Surface> surface_info, - mojo::InterfaceRequest<mojo::SurfaceClient> client_request); + WindowSurface(mojo::InterfacePtrInfo<mojo::Surface> surface_info, + mojo::InterfaceRequest<mojo::SurfaceClient> client_request); // SurfaceClient implementation: void ReturnResources( mojo::Array<mojo::ReturnedResourcePtr> resources) override; - ViewSurfaceClient* client_; + WindowSurfaceClient* client_; mojo::InterfacePtrInfo<mojo::Surface> surface_info_; mojo::InterfaceRequest<mojo::SurfaceClient> client_request_; mojo::SurfacePtr surface_; @@ -51,4 +51,4 @@ } // namespace mus -#endif // COMPONENTS_MUS_PUBLIC_CPP_VIEW_SURFACE_H_ +#endif // COMPONENTS_MUS_PUBLIC_CPP_WINDOW_SURFACE_H_
diff --git a/components/mus/public/cpp/view_surface_client.h b/components/mus/public/cpp/window_surface_client.h similarity index 82% rename from components/mus/public/cpp/view_surface_client.h rename to components/mus/public/cpp/window_surface_client.h index 0ac2c54..0906c8a 100644 --- a/components/mus/public/cpp/view_surface_client.h +++ b/components/mus/public/cpp/window_surface_client.h
@@ -7,16 +7,16 @@ namespace mus { -class ViewSurface; +class WindowSurface; -class ViewSurfaceClient { +class WindowSurfaceClient { public: virtual void OnResourcesReturned( - ViewSurface* surface, + WindowSurface* surface, mojo::Array<mojo::ReturnedResourcePtr> resources) = 0; protected: - ~ViewSurfaceClient() {} + ~WindowSurfaceClient() {} }; } // namespace mus
diff --git a/components/mus/public/cpp/window_tracker.cc b/components/mus/public/cpp/window_tracker.cc new file mode 100644 index 0000000..1fa1a4c --- /dev/null +++ b/components/mus/public/cpp/window_tracker.cc
@@ -0,0 +1,40 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/mus/public/cpp/window_tracker.h" + +namespace mus { + +WindowTracker::WindowTracker() {} + +WindowTracker::~WindowTracker() { + for (Windows::iterator i = windows_.begin(); i != windows_.end(); ++i) + (*i)->RemoveObserver(this); +} + +void WindowTracker::Add(Window* window) { + if (windows_.count(window)) + return; + + window->AddObserver(this); + windows_.insert(window); +} + +void WindowTracker::Remove(Window* window) { + if (windows_.count(window)) { + windows_.erase(window); + window->RemoveObserver(this); + } +} + +bool WindowTracker::Contains(Window* window) { + return windows_.count(window) > 0; +} + +void WindowTracker::OnWindowDestroying(Window* window) { + DCHECK_GT(windows_.count(window), 0u); + Remove(window); +} + +} // namespace mus
diff --git a/components/mus/public/cpp/window_tracker.h b/components/mus/public/cpp/window_tracker.h new file mode 100644 index 0000000..f2f4963 --- /dev/null +++ b/components/mus/public/cpp/window_tracker.h
@@ -0,0 +1,47 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_MUS_PUBLIC_CPP_WINDOW_TRACKER_H_ +#define COMPONENTS_MUS_PUBLIC_CPP_WINDOW_TRACKER_H_ + +#include <stdint.h> +#include <set> + +#include "components/mus/public/cpp/window_observer.h" +#include "third_party/mojo/src/mojo/public/cpp/system/macros.h" + +namespace mus { + +class WindowTracker : public WindowObserver { + public: + using Windows = std::set<Window*>; + + WindowTracker(); + ~WindowTracker() override; + + // Returns the set of windows being observed. + const std::set<Window*>& windows() const { return windows_; } + + // Adds |window| to the set of Windows being tracked. + void Add(Window* window); + + // Removes |window| from the set of windows being tracked. + void Remove(Window* window); + + // Returns true if |window| was previously added and has not been removed or + // deleted. + bool Contains(Window* window); + + // WindowObserver overrides: + void OnWindowDestroying(Window* window) override; + + private: + Windows windows_; + + MOJO_DISALLOW_COPY_AND_ASSIGN(WindowTracker); +}; + +} // namespace mus + +#endif // COMPONENTS_MUS_PUBLIC_CPP_WINDOW_TRACKER_H_
diff --git a/components/mus/public/cpp/view_tree_connection.h b/components/mus/public/cpp/window_tree_connection.h similarity index 60% rename from components/mus/public/cpp/view_tree_connection.h rename to components/mus/public/cpp/window_tree_connection.h index ee1095a0..d677b2a 100644 --- a/components/mus/public/cpp/view_tree_connection.h +++ b/components/mus/public/cpp/window_tree_connection.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_MUS_PUBLIC_CPP_VIEW_TREE_CONNECTION_H_ -#define COMPONENTS_MUS_PUBLIC_CPP_VIEW_TREE_CONNECTION_H_ +#ifndef COMPONENTS_MUS_PUBLIC_CPP_WINDOW_TREE_CONNECTION_H_ +#define COMPONENTS_MUS_PUBLIC_CPP_WINDOW_TREE_CONNECTION_H_ #include <string> @@ -11,45 +11,52 @@ #include "components/mus/public/interfaces/view_tree.mojom.h" #include "third_party/mojo/src/mojo/public/cpp/bindings/interface_request.h" +#if defined(OS_WIN) +// Windows headers define a macro for CreateWindow. +#if defined(CreateWindow) +#undef CreateWindow +#endif +#endif + namespace mus { -class View; -class ViewTreeDelegate; +class Window; +class WindowTreeDelegate; // Encapsulates a connection to a view tree. A unique connection is made // every time an app is embedded. -class ViewTreeConnection { +class WindowTreeConnection { public: enum class CreateType { // Indicates Create() should wait for OnEmbed(). If true, the - // ViewTreeConnection returned from Create() will have its root, otherwise - // the ViewTreeConnection will get the root at a later time. + // WindowTreeConnection returned from Create() will have its root, otherwise + // the WindowTreeConnection will get the root at a later time. WAIT_FOR_EMBED, DONT_WAIT_FOR_EMBED }; - virtual ~ViewTreeConnection() {} + virtual ~WindowTreeConnection() {} - // The returned ViewTreeConnection instance owns itself, and is deleted when + // The returned WindowTreeConnection instance owns itself, and is deleted when // the last root is destroyed or the connection to the service is broken. - static ViewTreeConnection* Create( - ViewTreeDelegate* delegate, + static WindowTreeConnection* Create( + WindowTreeDelegate* delegate, mojo::InterfaceRequest<mojo::ViewTreeClient> request, CreateType create_type); // Returns the root of this connection. - virtual View* GetRoot() = 0; + virtual Window* GetRoot() = 0; // Returns a View known to this connection. - virtual View* GetViewById(Id id) = 0; + virtual Window* GetWindowById(Id id) = 0; // Returns the focused view; null if focus is not yet known or another app is // focused. - virtual View* GetFocusedView() = 0; + virtual Window* GetFocusedWindow() = 0; // Creates and returns a new View (which is owned by the ViewManager). Views // are initially hidden, use SetVisible(true) to show. - virtual View* CreateView() = 0; + virtual Window* CreateWindow() = 0; // Returns true if ACCESS_POLICY_EMBED_ROOT was specified. virtual bool IsEmbedRoot() = 0; @@ -60,4 +67,4 @@ } // namespace mus -#endif // COMPONENTS_MUS_PUBLIC_CPP_VIEW_TREE_CONNECTION_H_ +#endif // COMPONENTS_MUS_PUBLIC_CPP_WINDOW_TREE_CONNECTION_H_
diff --git a/components/mus/public/cpp/view_tree_delegate.h b/components/mus/public/cpp/window_tree_delegate.h similarity index 70% rename from components/mus/public/cpp/view_tree_delegate.h rename to components/mus/public/cpp/window_tree_delegate.h index 2e2115e..2d6874b1 100644 --- a/components/mus/public/cpp/view_tree_delegate.h +++ b/components/mus/public/cpp/window_tree_delegate.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_MUS_PUBLIC_CPP_VIEW_TREE_DELEGATE_H_ -#define COMPONENTS_MUS_PUBLIC_CPP_VIEW_TREE_DELEGATE_H_ +#ifndef COMPONENTS_MUS_PUBLIC_CPP_WINDOW_TREE_DELEGATE_H_ +#define COMPONENTS_MUS_PUBLIC_CPP_WINDOW_TREE_DELEGATE_H_ #include <string> @@ -13,23 +13,24 @@ namespace mus { -class View; -class ViewTreeConnection; +class Window; +class WindowTreeConnection; // Interface implemented by an application using the view manager. // -// Each call to OnEmbed() results in a new ViewTreeConnection and new root View. -// ViewTreeConnection is deleted by any of the following: +// Each call to OnEmbed() results in a new WindowTreeConnection and new root +// View. +// WindowTreeConnection is deleted by any of the following: // . If the root of the connection is destroyed. This happens if the owner // of the root Embed()s another app in root, or the owner explicitly deletes // root. // . The connection to the view manager is lost. // . Explicitly by way of calling delete. // -// When the ViewTreeConnection is deleted all views are deleted (and observers +// When the WindowTreeConnection is deleted all views are deleted (and observers // notified). This is followed by notifying the delegate by way of // OnConnectionLost(). -class ViewTreeDelegate { +class WindowTreeDelegate { public: // Called when the application implementing this interface is embedded at // |root|. @@ -43,21 +44,21 @@ // the pipes connecting |services| and |exposed_services| to the embedder and // any services obtained from them are not broken and will continue to be // valid. - virtual void OnEmbed(View* root) = 0; + virtual void OnEmbed(Window* root) = 0; // Sent when another app is embedded in the same View as this connection. // Subsequently the root View and this object are destroyed (observers are // notified appropriately). virtual void OnUnembed(); - // Called from the destructor of ViewTreeConnection after all the Views have + // Called from the destructor of WindowTreeConnection after all the Views have // been destroyed. |connection| is no longer valid after this call. - virtual void OnConnectionLost(ViewTreeConnection* connection) = 0; + virtual void OnConnectionLost(WindowTreeConnection* connection) = 0; protected: - virtual ~ViewTreeDelegate() {} + virtual ~WindowTreeDelegate() {} }; } // namespace mus -#endif // COMPONENTS_MUS_PUBLIC_CPP_VIEW_TREE_DELEGATE_H_ +#endif // COMPONENTS_MUS_PUBLIC_CPP_WINDOW_TREE_DELEGATE_H_
diff --git a/components/mus/public/cpp/window_tree_host_factory.h b/components/mus/public/cpp/window_tree_host_factory.h new file mode 100644 index 0000000..c4e0790 --- /dev/null +++ b/components/mus/public/cpp/window_tree_host_factory.h
@@ -0,0 +1,37 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_MUS_PUBLIC_CPP_WINDOW_TREE_HOST_FACTORY_H_ +#define COMPONENTS_MUS_PUBLIC_CPP_WINDOW_TREE_HOST_FACTORY_H_ + +#include "base/basictypes.h" +#include "base/memory/scoped_ptr.h" +#include "components/mus/public/interfaces/view_tree.mojom.h" +#include "components/mus/public/interfaces/view_tree_host.mojom.h" +#include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h" + +namespace mojo { +class ApplicationImpl; +} + +namespace mus { + +class WindowTreeDelegate; + +// Uses |factory| to create a new |host|, providing the supplied |host_client| +// which may be null. |delegate| must not be null. +void CreateWindowTreeHost(mojo::ViewTreeHostFactory* factory, + mojo::ViewTreeHostClientPtr host_client, + WindowTreeDelegate* delegate, + mojo::ViewTreeHostPtr* host); + +// Creates a single host with no client by connecting to the view manager +// application. Useful only for tests and trivial UIs. +void CreateSingleWindowTreeHost(mojo::ApplicationImpl* app, + WindowTreeDelegate* delegate, + mojo::ViewTreeHostPtr* host); + +} // namespace mus + +#endif // COMPONENTS_MUS_PUBLIC_CPP_WINDOW_TREE_HOST_FACTORY_H_
diff --git a/components/mus/public/interfaces/view_tree.mojom b/components/mus/public/interfaces/view_tree.mojom index 47ed4c7..b9889c0 100644 --- a/components/mus/public/interfaces/view_tree.mojom +++ b/components/mus/public/interfaces/view_tree.mojom
@@ -98,17 +98,17 @@ // . |child| is an ancestor of |parent|. // . |child| is already a child of |parent|. // - // This may result in a connection getting OnViewDeleted(). See + // This may result in a connection getting OnWindowDeleted(). See // RemoveViewFromParent for details. AddView(uint32 parent, uint32 child) => (bool success); // Removes a view from its current parent. This fails if the view is not // valid or the view already has no parent. // - // Removing a view from a parent may result in OnViewDeleted() being sent to + // Removing a view from a parent may result in OnWindowDeleted() being sent to // other connections. For example, connection A has views 1 and 2, with 2 a // child of 1. Connection B has a root 1. If 2 is removed from 1 then B gets - // OnViewDeleted(). This is done as view 2 is effectively no longer visible to + // OnWindowDeleted(). This is done as view 2 is effectively no longer visible to // connection B. RemoveViewFromParent(uint32 view_id) => (bool success); @@ -144,7 +144,7 @@ // A view may only have one embedding in it at a time. Subsequent calls to // Embed() for the same view result in the currently embedded // ViewTreeClient being removed. The embedded app is told this by way of - // OnUnembed(), which is followed by OnViewDeleted() (as the connection no + // OnUnembed(), which is followed by OnWindowDeleted() (as the connection no // longer has access to the view). // // The embedder can detect when the embedded app disconnects by way of @@ -173,7 +173,7 @@ // Changes to views are not sent to the connection that originated the // change. For example, if connection 1 changes the bounds of a view by calling -// SetBounds(), connection 1 does not receive OnViewBoundsChanged(). +// SetBounds(), connection 1 does not receive OnWindowBoundsChanged(). interface ViewTreeClient { // Invoked when the client application has been embedded at |root|. // See Embed() on ViewTree for more details. |tree| will be a handle back to @@ -196,13 +196,13 @@ OnUnembed(); // Invoked when a view's bounds have changed. - OnViewBoundsChanged(uint32 view, + OnWindowBoundsChanged(uint32 view, mojo.Rect old_bounds, mojo.Rect new_bounds); // Invoked when the viewport metrics for the view have changed. // Clients are expected to propagate this to the view tree. - OnViewViewportMetricsChanged(mojo.ViewportMetrics old_metrics, + OnWindowViewportMetricsChanged(mojo.ViewportMetrics old_metrics, mojo.ViewportMetrics new_metrics); // Invoked when a change is done to the hierarchy. A value of 0 is used to @@ -211,21 +211,21 @@ // |views| contains any views that are that the client has not been told // about. This is not sent for hierarchy changes of views not known to this // client or not attached to the tree. - OnViewHierarchyChanged(uint32 view, + OnWindowHierarchyChanged(uint32 view, uint32 new_parent, uint32 old_parent, array<ViewData> views); // Invoked when the order of views within a parent changes. - OnViewReordered(uint32 view_id, + OnWindowReordered(uint32 view_id, uint32 relative_view_id, OrderDirection direction); // Invoked when a view is deleted. - OnViewDeleted(uint32 view); + OnWindowDeleted(uint32 view); // Invoked when the visibility of the specified view changes. - OnViewVisibilityChanged(uint32 view, bool visible); + OnWindowVisibilityChanged(uint32 view, bool visible); // Invoked when a change to the visibility of |view| or one if it's ancestors // is done such that the drawn state changes. This is only invoked for the @@ -236,15 +236,15 @@ // the drawn state of B1 has changed (to false), but is not told anything // about B2 as it's drawn state can be calculated from that of B1. // - // NOTE: This is not invoked if OnViewVisibilityChanged() is invoked. - OnViewDrawnStateChanged(uint32 view, bool drawn); + // NOTE: This is not invoked if OnWindowVisibilityChanged() is invoked. + OnWindowDrawnStateChanged(uint32 view, bool drawn); // Invoked when a view property is changed. If this change is a removal, // |new_data| is null. - OnViewSharedPropertyChanged(uint32 view, string name, array<uint8>? new_data); + OnWindowSharedPropertyChanged(uint32 view, string name, array<uint8>? new_data); // Invoked when an event is targeted at the specified view. - OnViewInputEvent(uint32 view, mojo.Event event) => (); + OnWindowInputEvent(uint32 view, mojo.Event event) => (); - OnViewFocused(uint32 focused_view_id); + OnWindowFocused(uint32 focused_view_id); };
diff --git a/components/mus/public/interfaces/view_tree_host.mojom b/components/mus/public/interfaces/view_tree_host.mojom index 74ef56b..2d436bde 100644 --- a/components/mus/public/interfaces/view_tree_host.mojom +++ b/components/mus/public/interfaces/view_tree_host.mojom
@@ -35,7 +35,7 @@ }; interface ViewTreeHostFactory { - CreateViewTreeHost(ViewTreeHost& view_tree_host, - ViewTreeHostClient? host_client, - ViewTreeClient tree_client); + CreateWindowTreeHost(ViewTreeHost& view_tree_host, + ViewTreeHostClient? host_client, + ViewTreeClient tree_client); };
diff --git a/components/mus/public/interfaces/window_manager.mojom b/components/mus/public/interfaces/window_manager.mojom index ea51794..0bedd1f 100644 --- a/components/mus/public/interfaces/window_manager.mojom +++ b/components/mus/public/interfaces/window_manager.mojom
@@ -7,6 +7,21 @@ import "components/mus/public/interfaces/view_tree.mojom"; import "ui/mojo/geometry/geometry.mojom"; +enum Rotation { + VALUE_0, + VALUE_90, + VALUE_180, + VALUE_270, +}; + +struct Display { + int64 id; + mojo.Rect bounds; + mojo.Rect work_area; + float device_pixel_ratio; + Rotation rotation; +}; + // Represents a core interface that should be implemented by any window manager // built on top of Mus. // For security reasons, methods that take view_ids can only pass view ids @@ -18,4 +33,6 @@ // Resizes the corresponding view to |size| and centers it in the current // context. CenterWindow(uint32 view_id, mojo.Size size); + + GetDisplays() => (array<Display> displays); };
diff --git a/components/mus/vm/access_policy.h b/components/mus/vm/access_policy.h index d28e678..f2862b4 100644 --- a/components/mus/vm/access_policy.h +++ b/components/mus/vm/access_policy.h
@@ -35,7 +35,7 @@ virtual bool CanEmbed(const ServerView* view, uint32_t policy_bitmask) const = 0; virtual bool CanChangeViewVisibility(const ServerView* view) const = 0; - virtual bool CanSetViewSurfaceId(const ServerView* view) const = 0; + virtual bool CanSetWindowSurfaceId(const ServerView* view) const = 0; virtual bool CanSetViewBounds(const ServerView* view) const = 0; virtual bool CanSetViewProperties(const ServerView* view) const = 0; virtual bool CanSetViewTextInputState(const ServerView* view) const = 0;
diff --git a/components/mus/vm/default_access_policy.cc b/components/mus/vm/default_access_policy.cc index 852f310..f2a049a 100644 --- a/components/mus/vm/default_access_policy.cc +++ b/components/mus/vm/default_access_policy.cc
@@ -73,9 +73,10 @@ delegate_->IsRootForAccessPolicy(view->id()); } -bool DefaultAccessPolicy::CanSetViewSurfaceId(const ServerView* view) const { +bool DefaultAccessPolicy::CanSetWindowSurfaceId(const ServerView* view) const { // Once a view embeds another app, the embedder app is no longer able to - // call SetViewSurfaceId() - this ability is transferred to the embedded app. + // call SetWindowSurfaceId() - this ability is transferred to the embedded + // app. if (delegate_->IsViewRootOfAnotherConnectionForAccessPolicy(view)) return false; return WasCreatedByThisConnection(view) ||
diff --git a/components/mus/vm/default_access_policy.h b/components/mus/vm/default_access_policy.h index 194c903..6bda02e 100644 --- a/components/mus/vm/default_access_policy.h +++ b/components/mus/vm/default_access_policy.h
@@ -31,7 +31,7 @@ bool CanDescendIntoViewForViewTree(const ServerView* view) const override; bool CanEmbed(const ServerView* view, uint32_t policy_bitmask) const override; bool CanChangeViewVisibility(const ServerView* view) const override; - bool CanSetViewSurfaceId(const ServerView* view) const override; + bool CanSetWindowSurfaceId(const ServerView* view) const override; bool CanSetViewBounds(const ServerView* view) const override; bool CanSetViewProperties(const ServerView* view) const override; bool CanSetViewTextInputState(const ServerView* view) const override;
diff --git a/components/mus/vm/test_change_tracker.cc b/components/mus/vm/test_change_tracker.cc index 3a3dd978..9ff3b114 100644 --- a/components/mus/vm/test_change_tracker.cc +++ b/components/mus/vm/test_change_tracker.cc
@@ -187,9 +187,9 @@ AddChange(change); } -void TestChangeTracker::OnViewBoundsChanged(Id view_id, - mojo::RectPtr old_bounds, - mojo::RectPtr new_bounds) { +void TestChangeTracker::OnWindowBoundsChanged(Id view_id, + mojo::RectPtr old_bounds, + mojo::RectPtr new_bounds) { Change change; change.type = CHANGE_TYPE_NODE_BOUNDS_CHANGED; change.view_id = view_id; @@ -210,7 +210,7 @@ AddChange(change); } -void TestChangeTracker::OnViewViewportMetricsChanged( +void TestChangeTracker::OnWindowViewportMetricsChanged( mojo::ViewportMetricsPtr old_metrics, mojo::ViewportMetricsPtr new_metrics) { Change change; @@ -219,10 +219,10 @@ AddChange(change); } -void TestChangeTracker::OnViewHierarchyChanged(Id view_id, - Id new_parent_id, - Id old_parent_id, - Array<ViewDataPtr> views) { +void TestChangeTracker::OnWindowHierarchyChanged(Id view_id, + Id new_parent_id, + Id old_parent_id, + Array<ViewDataPtr> views) { Change change; change.type = CHANGE_TYPE_NODE_HIERARCHY_CHANGED; change.view_id = view_id; @@ -232,9 +232,9 @@ AddChange(change); } -void TestChangeTracker::OnViewReordered(Id view_id, - Id relative_view_id, - mojo::OrderDirection direction) { +void TestChangeTracker::OnWindowReordered(Id view_id, + Id relative_view_id, + mojo::OrderDirection direction) { Change change; change.type = CHANGE_TYPE_NODE_REORDERED; change.view_id = view_id; @@ -243,14 +243,14 @@ AddChange(change); } -void TestChangeTracker::OnViewDeleted(Id view_id) { +void TestChangeTracker::OnWindowDeleted(Id view_id) { Change change; change.type = CHANGE_TYPE_NODE_DELETED; change.view_id = view_id; AddChange(change); } -void TestChangeTracker::OnViewVisibilityChanged(Id view_id, bool visible) { +void TestChangeTracker::OnWindowVisibilityChanged(Id view_id, bool visible) { Change change; change.type = CHANGE_TYPE_NODE_VISIBILITY_CHANGED; change.view_id = view_id; @@ -258,7 +258,7 @@ AddChange(change); } -void TestChangeTracker::OnViewDrawnStateChanged(Id view_id, bool drawn) { +void TestChangeTracker::OnWindowDrawnStateChanged(Id view_id, bool drawn) { Change change; change.type = CHANGE_TYPE_NODE_DRAWN_STATE_CHANGED; change.view_id = view_id; @@ -266,7 +266,7 @@ AddChange(change); } -void TestChangeTracker::OnViewInputEvent(Id view_id, mojo::EventPtr event) { +void TestChangeTracker::OnWindowInputEvent(Id view_id, mojo::EventPtr event) { Change change; change.type = CHANGE_TYPE_INPUT_EVENT; change.view_id = view_id; @@ -274,9 +274,9 @@ AddChange(change); } -void TestChangeTracker::OnViewSharedPropertyChanged(Id view_id, - String name, - Array<uint8_t> data) { +void TestChangeTracker::OnWindowSharedPropertyChanged(Id view_id, + String name, + Array<uint8_t> data) { Change change; change.type = CHANGE_TYPE_PROPERTY_CHANGED; change.view_id = view_id; @@ -288,7 +288,7 @@ AddChange(change); } -void TestChangeTracker::OnViewFocused(Id view_id) { +void TestChangeTracker::OnWindowFocused(Id view_id) { Change change; change.type = CHANGE_TYPE_FOCUSED; change.view_id = view_id;
diff --git a/components/mus/vm/test_change_tracker.h b/components/mus/vm/test_change_tracker.h index 1896de2..aa1514b6 100644 --- a/components/mus/vm/test_change_tracker.h +++ b/components/mus/vm/test_change_tracker.h
@@ -120,26 +120,26 @@ void OnEmbed(ConnectionSpecificId connection_id, mojo::ViewDataPtr root); void OnEmbeddedAppDisconnected(Id view_id); void OnUnembed(); - void OnViewBoundsChanged(Id view_id, - mojo::RectPtr old_bounds, - mojo::RectPtr new_bounds); - void OnViewViewportMetricsChanged(mojo::ViewportMetricsPtr old_bounds, - mojo::ViewportMetricsPtr new_bounds); - void OnViewHierarchyChanged(Id view_id, - Id new_parent_id, - Id old_parent_id, - mojo::Array<mojo::ViewDataPtr> views); - void OnViewReordered(Id view_id, - Id relative_view_id, - mojo::OrderDirection direction); - void OnViewDeleted(Id view_id); - void OnViewVisibilityChanged(Id view_id, bool visible); - void OnViewDrawnStateChanged(Id view_id, bool drawn); - void OnViewInputEvent(Id view_id, mojo::EventPtr event); - void OnViewSharedPropertyChanged(Id view_id, - mojo::String name, - mojo::Array<uint8_t> data); - void OnViewFocused(Id view_id); + void OnWindowBoundsChanged(Id view_id, + mojo::RectPtr old_bounds, + mojo::RectPtr new_bounds); + void OnWindowViewportMetricsChanged(mojo::ViewportMetricsPtr old_bounds, + mojo::ViewportMetricsPtr new_bounds); + void OnWindowHierarchyChanged(Id view_id, + Id new_parent_id, + Id old_parent_id, + mojo::Array<mojo::ViewDataPtr> views); + void OnWindowReordered(Id view_id, + Id relative_view_id, + mojo::OrderDirection direction); + void OnWindowDeleted(Id view_id); + void OnWindowVisibilityChanged(Id view_id, bool visible); + void OnWindowDrawnStateChanged(Id view_id, bool drawn); + void OnWindowInputEvent(Id view_id, mojo::EventPtr event); + void OnWindowSharedPropertyChanged(Id view_id, + mojo::String name, + mojo::Array<uint8_t> data); + void OnWindowFocused(Id view_id); void DelegateEmbed(const mojo::String& url); private:
diff --git a/components/mus/vm/view_manager_client_apptest.cc b/components/mus/vm/view_manager_client_apptest.cc index 1b38820..9d6e1af 100644 --- a/components/mus/vm/view_manager_client_apptest.cc +++ b/components/mus/vm/view_manager_client_apptest.cc
@@ -5,11 +5,11 @@ #include "base/bind.h" #include "base/logging.h" #include "base/run_loop.h" -#include "components/mus/public/cpp/tests/view_manager_test_base.h" +#include "components/mus/public/cpp/tests/window_server_test_base.h" #include "components/mus/public/cpp/util.h" -#include "components/mus/public/cpp/view_observer.h" -#include "components/mus/public/cpp/view_tree_connection.h" -#include "components/mus/public/cpp/view_tree_delegate.h" +#include "components/mus/public/cpp/window_observer.h" +#include "components/mus/public/cpp/window_tree_connection.h" +#include "components/mus/public/cpp/window_tree_delegate.h" #include "mojo/application/public/cpp/application_connection.h" #include "mojo/application/public/cpp/application_impl.h" #include "mojo/application/public/cpp/application_test_base.h" @@ -19,133 +19,142 @@ namespace { -class BoundsChangeObserver : public ViewObserver { +class BoundsChangeObserver : public WindowObserver { public: - explicit BoundsChangeObserver(View* view) : view_(view) { - view_->AddObserver(this); + explicit BoundsChangeObserver(Window* window) : window_(window) { + window_->AddObserver(this); } - ~BoundsChangeObserver() override { view_->RemoveObserver(this); } + ~BoundsChangeObserver() override { window_->RemoveObserver(this); } private: - // Overridden from ViewObserver: - void OnViewBoundsChanged(View* view, - const mojo::Rect& old_bounds, - const mojo::Rect& new_bounds) override { - DCHECK_EQ(view, view_); - EXPECT_TRUE(ViewManagerTestBase::QuitRunLoop()); + // Overridden from WindowObserver: + void OnWindowBoundsChanged(Window* window, + const mojo::Rect& old_bounds, + const mojo::Rect& new_bounds) override { + DCHECK_EQ(window, window_); + EXPECT_TRUE(WindowServerTestBase::QuitRunLoop()); } - View* view_; + Window* window_; MOJO_DISALLOW_COPY_AND_ASSIGN(BoundsChangeObserver); }; -// Wait until the bounds of the supplied view change; returns false on timeout. -bool WaitForBoundsToChange(View* view) { - BoundsChangeObserver observer(view); - return ViewManagerTestBase::DoRunLoopWithTimeout(); +// Wait until the bounds of the supplied window change; returns false on +// timeout. +bool WaitForBoundsToChange(Window* window) { + BoundsChangeObserver observer(window); + return WindowServerTestBase::DoRunLoopWithTimeout(); } -// Spins a run loop until the tree beginning at |root| has |tree_size| views +// Spins a run loop until the tree beginning at |root| has |tree_size| windows // (including |root|). -class TreeSizeMatchesObserver : public ViewObserver { +class TreeSizeMatchesObserver : public WindowObserver { public: - TreeSizeMatchesObserver(View* tree, size_t tree_size) + TreeSizeMatchesObserver(Window* tree, size_t tree_size) : tree_(tree), tree_size_(tree_size) { tree_->AddObserver(this); } ~TreeSizeMatchesObserver() override { tree_->RemoveObserver(this); } - bool IsTreeCorrectSize() { return CountViews(tree_) == tree_size_; } + bool IsTreeCorrectSize() { return CountWindows(tree_) == tree_size_; } private: - // Overridden from ViewObserver: + // Overridden from WindowObserver: void OnTreeChanged(const TreeChangeParams& params) override { if (IsTreeCorrectSize()) - EXPECT_TRUE(ViewManagerTestBase::QuitRunLoop()); + EXPECT_TRUE(WindowServerTestBase::QuitRunLoop()); } - size_t CountViews(const View* view) const { + size_t CountWindows(const Window* window) const { size_t count = 1; - View::Children::const_iterator it = view->children().begin(); - for (; it != view->children().end(); ++it) - count += CountViews(*it); + Window::Children::const_iterator it = window->children().begin(); + for (; it != window->children().end(); ++it) + count += CountWindows(*it); return count; } - View* tree_; + Window* tree_; size_t tree_size_; MOJO_DISALLOW_COPY_AND_ASSIGN(TreeSizeMatchesObserver); }; -// Wait until |view| has |tree_size| descendants; returns false on timeout. The -// count includes |view|. For example, if you want to wait for |view| to have +// Wait until |window| has |tree_size| descendants; returns false on timeout. +// The +// count includes |window|. For example, if you want to wait for |window| to +// have // a single child, use a |tree_size| of 2. -bool WaitForTreeSizeToMatch(View* view, size_t tree_size) { - TreeSizeMatchesObserver observer(view, tree_size); +bool WaitForTreeSizeToMatch(Window* window, size_t tree_size) { + TreeSizeMatchesObserver observer(window, tree_size); return observer.IsTreeCorrectSize() || - ViewManagerTestBase::DoRunLoopWithTimeout(); + WindowServerTestBase::DoRunLoopWithTimeout(); } -class OrderChangeObserver : public ViewObserver { +class OrderChangeObserver : public WindowObserver { public: - OrderChangeObserver(View* view) : view_(view) { view_->AddObserver(this); } - ~OrderChangeObserver() override { view_->RemoveObserver(this); } + OrderChangeObserver(Window* window) : window_(window) { + window_->AddObserver(this); + } + ~OrderChangeObserver() override { window_->RemoveObserver(this); } private: - // Overridden from ViewObserver: - void OnViewReordered(View* view, - View* relative_view, - mojo::OrderDirection direction) override { - DCHECK_EQ(view, view_); - EXPECT_TRUE(ViewManagerTestBase::QuitRunLoop()); + // Overridden from WindowObserver: + void OnWindowReordered(Window* window, + Window* relative_window, + mojo::OrderDirection direction) override { + DCHECK_EQ(window, window_); + EXPECT_TRUE(WindowServerTestBase::QuitRunLoop()); } - View* view_; + Window* window_; MOJO_DISALLOW_COPY_AND_ASSIGN(OrderChangeObserver); }; -// Wait until |view|'s tree size matches |tree_size|; returns false on timeout. -bool WaitForOrderChange(ViewTreeConnection* connection, View* view) { - OrderChangeObserver observer(view); - return ViewManagerTestBase::DoRunLoopWithTimeout(); +// Wait until |window|'s tree size matches |tree_size|; returns false on +// timeout. +bool WaitForOrderChange(WindowTreeConnection* connection, Window* window) { + OrderChangeObserver observer(window); + return WindowServerTestBase::DoRunLoopWithTimeout(); } -// Tracks a view's destruction. Query is_valid() for current state. -class ViewTracker : public ViewObserver { +// Tracks a window's destruction. Query is_valid() for current state. +class WindowTracker : public WindowObserver { public: - explicit ViewTracker(View* view) : view_(view) { view_->AddObserver(this); } - ~ViewTracker() override { - if (view_) - view_->RemoveObserver(this); + explicit WindowTracker(Window* window) : window_(window) { + window_->AddObserver(this); + } + ~WindowTracker() override { + if (window_) + window_->RemoveObserver(this); } - bool is_valid() const { return !!view_; } + bool is_valid() const { return !!window_; } private: - // Overridden from ViewObserver: - void OnViewDestroyed(View* view) override { - DCHECK_EQ(view, view_); - view_ = nullptr; + // Overridden from WindowObserver: + void OnWindowDestroyed(Window* window) override { + DCHECK_EQ(window, window_); + window_ = nullptr; } - View* view_; + Window* window_; - MOJO_DISALLOW_COPY_AND_ASSIGN(ViewTracker); + MOJO_DISALLOW_COPY_AND_ASSIGN(WindowTracker); }; } // namespace -// ViewManager ----------------------------------------------------------------- +// WindowServer +// ----------------------------------------------------------------- struct EmbedResult { - EmbedResult(ViewTreeConnection* connection, ConnectionSpecificId id) + EmbedResult(WindowTreeConnection* connection, ConnectionSpecificId id) : connection(connection), connection_id(id) {} EmbedResult() : connection(nullptr), connection_id(0) {} - ViewTreeConnection* connection; + WindowTreeConnection* connection; // The id supplied to the callback from OnEmbed(). Depending upon the // access policy this may or may not match the connection id of @@ -153,29 +162,30 @@ ConnectionSpecificId connection_id; }; -// These tests model synchronization of two peer connections to the view manager -// service, that are given access to some root view. +// These tests model synchronization of two peer connections to the window +// manager +// service, that are given access to some root window. -class ViewManagerTest : public ViewManagerTestBase { +class WindowServerTest : public WindowServerTestBase { public: - ViewManagerTest() {} + WindowServerTest() {} - // Embeds another version of the test app @ view. This runs a run loop until - // a response is received, or a timeout. On success the new ViewManager is + // Embeds another version of the test app @ window. This runs a run loop until + // a response is received, or a timeout. On success the new WindowServer is // returned. - EmbedResult Embed(View* view) { - return Embed(view, mojo::ViewTree::ACCESS_POLICY_DEFAULT); + EmbedResult Embed(Window* window) { + return Embed(window, mojo::ViewTree::ACCESS_POLICY_DEFAULT); } - EmbedResult Embed(View* view, uint32_t access_policy_bitmask) { + EmbedResult Embed(Window* window, uint32_t access_policy_bitmask) { DCHECK(!embed_details_); embed_details_.reset(new EmbedDetails); - view->Embed(ConnectToApplicationAndGetViewManagerClient(), - access_policy_bitmask, - base::Bind(&ViewManagerTest::EmbedCallbackImpl, - base::Unretained(this))); + window->Embed(ConnectToApplicationAndGetWindowServerClient(), + access_policy_bitmask, + base::Bind(&WindowServerTest::EmbedCallbackImpl, + base::Unretained(this))); embed_details_->waiting = true; - if (!ViewManagerTestBase::DoRunLoopWithTimeout()) + if (!WindowServerTestBase::DoRunLoopWithTimeout()) return EmbedResult(); const EmbedResult result(embed_details_->connection, embed_details_->connection_id); @@ -185,7 +195,7 @@ // Establishes a connection to this application and asks for a // ViewTreeClient. - mojo::ViewTreeClientPtr ConnectToApplicationAndGetViewManagerClient() { + mojo::ViewTreeClientPtr ConnectToApplicationAndGetWindowServerClient() { mojo::URLRequestPtr request(mojo::URLRequest::New()); request->url = mojo::String::From(application_impl()->url()); scoped_ptr<mojo::ApplicationConnection> connection = @@ -195,20 +205,20 @@ return client.Pass(); } - // ViewManagerTestBase: - void OnEmbed(View* root) override { + // WindowServerTestBase: + void OnEmbed(Window* root) override { if (!embed_details_) { - ViewManagerTestBase::OnEmbed(root); + WindowServerTestBase::OnEmbed(root); return; } embed_details_->connection = root->connection(); if (embed_details_->callback_run) - EXPECT_TRUE(ViewManagerTestBase::QuitRunLoop()); + EXPECT_TRUE(WindowServerTestBase::QuitRunLoop()); } private: - // Used to track the state of a call to view->Embed(). + // Used to track the state of a call to window->Embed(). struct EmbedDetails { EmbedDetails() : callback_run(false), @@ -229,9 +239,9 @@ // Connection id supplied to the Embed() callback. ConnectionSpecificId connection_id; - // The ViewTreeConnection that resulted from the Embed(). null if |result| + // The WindowTreeConnection that resulted from the Embed(). null if |result| // is false. - ViewTreeConnection* connection; + WindowTreeConnection* connection; }; void EmbedCallbackImpl(bool result, ConnectionSpecificId connection_id) { @@ -239,217 +249,218 @@ embed_details_->result = result; embed_details_->connection_id = connection_id; if (embed_details_->waiting && (!result || embed_details_->connection)) - EXPECT_TRUE(ViewManagerTestBase::QuitRunLoop()); + EXPECT_TRUE(WindowServerTestBase::QuitRunLoop()); } scoped_ptr<EmbedDetails> embed_details_; - MOJO_DISALLOW_COPY_AND_ASSIGN(ViewManagerTest); + MOJO_DISALLOW_COPY_AND_ASSIGN(WindowServerTest); }; -TEST_F(ViewManagerTest, RootView) { +TEST_F(WindowServerTest, RootWindow) { ASSERT_NE(nullptr, window_manager()); EXPECT_NE(nullptr, window_manager()->GetRoot()); } -TEST_F(ViewManagerTest, Embed) { - View* view = window_manager()->CreateView(); - ASSERT_NE(nullptr, view); - view->SetVisible(true); - window_manager()->GetRoot()->AddChild(view); - ViewTreeConnection* embedded = Embed(view).connection; +TEST_F(WindowServerTest, Embed) { + Window* window = window_manager()->CreateWindow(); + ASSERT_NE(nullptr, window); + window->SetVisible(true); + window_manager()->GetRoot()->AddChild(window); + WindowTreeConnection* embedded = Embed(window).connection; ASSERT_NE(nullptr, embedded); - View* view_in_embedded = embedded->GetRoot(); - ASSERT_NE(nullptr, view_in_embedded); - EXPECT_EQ(view->id(), view_in_embedded->id()); - EXPECT_EQ(nullptr, view_in_embedded->parent()); - EXPECT_TRUE(view_in_embedded->children().empty()); + Window* window_in_embedded = embedded->GetRoot(); + ASSERT_NE(nullptr, window_in_embedded); + EXPECT_EQ(window->id(), window_in_embedded->id()); + EXPECT_EQ(nullptr, window_in_embedded->parent()); + EXPECT_TRUE(window_in_embedded->children().empty()); } -// Window manager has two views, N1 and N11. Embeds A at N1. A should not see +// Window manager has two windows, N1 and N11. Embeds A at N1. A should not see // N11. -TEST_F(ViewManagerTest, EmbeddedDoesntSeeChild) { - View* view = window_manager()->CreateView(); - ASSERT_NE(nullptr, view); - view->SetVisible(true); - window_manager()->GetRoot()->AddChild(view); - View* nested = window_manager()->CreateView(); +TEST_F(WindowServerTest, EmbeddedDoesntSeeChild) { + Window* window = window_manager()->CreateWindow(); + ASSERT_NE(nullptr, window); + window->SetVisible(true); + window_manager()->GetRoot()->AddChild(window); + Window* nested = window_manager()->CreateWindow(); ASSERT_NE(nullptr, nested); nested->SetVisible(true); - view->AddChild(nested); + window->AddChild(nested); - ViewTreeConnection* embedded = Embed(view).connection; + WindowTreeConnection* embedded = Embed(window).connection; ASSERT_NE(nullptr, embedded); - View* view_in_embedded = embedded->GetRoot(); - EXPECT_EQ(view->id(), view_in_embedded->id()); - EXPECT_EQ(nullptr, view_in_embedded->parent()); - EXPECT_TRUE(view_in_embedded->children().empty()); + Window* window_in_embedded = embedded->GetRoot(); + EXPECT_EQ(window->id(), window_in_embedded->id()); + EXPECT_EQ(nullptr, window_in_embedded->parent()); + EXPECT_TRUE(window_in_embedded->children().empty()); } // TODO(beng): write a replacement test for the one that once existed here: // This test validates the following scenario: -// - a view originating from one connection -// - a view originating from a second connection -// + the connection originating the view is destroyed -// -> the view should still exist (since the second connection is live) but -// should be disconnected from any views. +// - a window originating from one connection +// - a window originating from a second connection +// + the connection originating the window is destroyed +// -> the window should still exist (since the second connection is live) but +// should be disconnected from any windows. // http://crbug.com/396300 // // TODO(beng): The new test should validate the scenario as described above // except that the second connection still has a valid tree. -// Verifies that bounds changes applied to a view hierarchy in one connection +// Verifies that bounds changes applied to a window hierarchy in one connection // are reflected to another. -TEST_F(ViewManagerTest, SetBounds) { - View* view = window_manager()->CreateView(); - view->SetVisible(true); - window_manager()->GetRoot()->AddChild(view); - ViewTreeConnection* embedded = Embed(view).connection; +TEST_F(WindowServerTest, SetBounds) { + Window* window = window_manager()->CreateWindow(); + window->SetVisible(true); + window_manager()->GetRoot()->AddChild(window); + WindowTreeConnection* embedded = Embed(window).connection; ASSERT_NE(nullptr, embedded); - View* view_in_embedded = embedded->GetViewById(view->id()); - EXPECT_EQ(view->bounds(), view_in_embedded->bounds()); + Window* window_in_embedded = embedded->GetWindowById(window->id()); + EXPECT_EQ(window->bounds(), window_in_embedded->bounds()); mojo::Rect rect; rect.width = rect.height = 100; - view->SetBounds(rect); - ASSERT_TRUE(WaitForBoundsToChange(view_in_embedded)); - EXPECT_EQ(view->bounds(), view_in_embedded->bounds()); + window->SetBounds(rect); + ASSERT_TRUE(WaitForBoundsToChange(window_in_embedded)); + EXPECT_EQ(window->bounds(), window_in_embedded->bounds()); } -// Verifies that bounds changes applied to a view owned by a different +// Verifies that bounds changes applied to a window owned by a different // connection are refused. -TEST_F(ViewManagerTest, SetBoundsSecurity) { - View* view = window_manager()->CreateView(); - view->SetVisible(true); - window_manager()->GetRoot()->AddChild(view); - ViewTreeConnection* embedded = Embed(view).connection; +TEST_F(WindowServerTest, SetBoundsSecurity) { + Window* window = window_manager()->CreateWindow(); + window->SetVisible(true); + window_manager()->GetRoot()->AddChild(window); + WindowTreeConnection* embedded = Embed(window).connection; ASSERT_NE(nullptr, embedded); - View* view_in_embedded = embedded->GetViewById(view->id()); + Window* window_in_embedded = embedded->GetWindowById(window->id()); mojo::Rect rect; rect.width = 800; rect.height = 600; - view->SetBounds(rect); - ASSERT_TRUE(WaitForBoundsToChange(view_in_embedded)); + window->SetBounds(rect); + ASSERT_TRUE(WaitForBoundsToChange(window_in_embedded)); rect.width = 1024; rect.height = 768; - view_in_embedded->SetBounds(rect); + window_in_embedded->SetBounds(rect); // Bounds change should have been rejected. - EXPECT_EQ(view->bounds(), view_in_embedded->bounds()); + EXPECT_EQ(window->bounds(), window_in_embedded->bounds()); } -// Verifies that a view can only be destroyed by the connection that created it. -TEST_F(ViewManagerTest, DestroySecurity) { - View* view = window_manager()->CreateView(); - view->SetVisible(true); - window_manager()->GetRoot()->AddChild(view); - ViewTreeConnection* embedded = Embed(view).connection; +// Verifies that a window can only be destroyed by the connection that created +// it. +TEST_F(WindowServerTest, DestroySecurity) { + Window* window = window_manager()->CreateWindow(); + window->SetVisible(true); + window_manager()->GetRoot()->AddChild(window); + WindowTreeConnection* embedded = Embed(window).connection; ASSERT_NE(nullptr, embedded); - View* view_in_embedded = embedded->GetViewById(view->id()); + Window* window_in_embedded = embedded->GetWindowById(window->id()); - ViewTracker tracker2(view_in_embedded); - view_in_embedded->Destroy(); - // View should not have been destroyed. + WindowTracker tracker2(window_in_embedded); + window_in_embedded->Destroy(); + // Window should not have been destroyed. EXPECT_TRUE(tracker2.is_valid()); - ViewTracker tracker1(view); - view->Destroy(); + WindowTracker tracker1(window); + window->Destroy(); EXPECT_FALSE(tracker1.is_valid()); } -TEST_F(ViewManagerTest, MultiRoots) { - View* view1 = window_manager()->CreateView(); - view1->SetVisible(true); - window_manager()->GetRoot()->AddChild(view1); - View* view2 = window_manager()->CreateView(); - view2->SetVisible(true); - window_manager()->GetRoot()->AddChild(view2); - ViewTreeConnection* embedded1 = Embed(view1).connection; +TEST_F(WindowServerTest, MultiRoots) { + Window* window1 = window_manager()->CreateWindow(); + window1->SetVisible(true); + window_manager()->GetRoot()->AddChild(window1); + Window* window2 = window_manager()->CreateWindow(); + window2->SetVisible(true); + window_manager()->GetRoot()->AddChild(window2); + WindowTreeConnection* embedded1 = Embed(window1).connection; ASSERT_NE(nullptr, embedded1); - ViewTreeConnection* embedded2 = Embed(view2).connection; + WindowTreeConnection* embedded2 = Embed(window2).connection; ASSERT_NE(nullptr, embedded2); EXPECT_NE(embedded1, embedded2); } // TODO(alhaad): Currently, the RunLoop gets stuck waiting for order change. // Debug and re-enable this. -TEST_F(ViewManagerTest, DISABLED_Reorder) { - View* view1 = window_manager()->CreateView(); - view1->SetVisible(true); - window_manager()->GetRoot()->AddChild(view1); +TEST_F(WindowServerTest, DISABLED_Reorder) { + Window* window1 = window_manager()->CreateWindow(); + window1->SetVisible(true); + window_manager()->GetRoot()->AddChild(window1); - ViewTreeConnection* embedded = Embed(view1).connection; + WindowTreeConnection* embedded = Embed(window1).connection; ASSERT_NE(nullptr, embedded); - View* view11 = embedded->CreateView(); - view11->SetVisible(true); - embedded->GetRoot()->AddChild(view11); - View* view12 = embedded->CreateView(); - view12->SetVisible(true); - embedded->GetRoot()->AddChild(view12); + Window* window11 = embedded->CreateWindow(); + window11->SetVisible(true); + embedded->GetRoot()->AddChild(window11); + Window* window12 = embedded->CreateWindow(); + window12->SetVisible(true); + embedded->GetRoot()->AddChild(window12); - View* root_in_embedded = embedded->GetRoot(); + Window* root_in_embedded = embedded->GetRoot(); { ASSERT_TRUE(WaitForTreeSizeToMatch(root_in_embedded, 3u)); - view11->MoveToFront(); + window11->MoveToFront(); ASSERT_TRUE(WaitForOrderChange(embedded, root_in_embedded)); EXPECT_EQ(root_in_embedded->children().front(), - embedded->GetViewById(view12->id())); + embedded->GetWindowById(window12->id())); EXPECT_EQ(root_in_embedded->children().back(), - embedded->GetViewById(view11->id())); + embedded->GetWindowById(window11->id())); } { - view11->MoveToBack(); + window11->MoveToBack(); ASSERT_TRUE( - WaitForOrderChange(embedded, embedded->GetViewById(view11->id()))); + WaitForOrderChange(embedded, embedded->GetWindowById(window11->id()))); EXPECT_EQ(root_in_embedded->children().front(), - embedded->GetViewById(view11->id())); + embedded->GetWindowById(window11->id())); EXPECT_EQ(root_in_embedded->children().back(), - embedded->GetViewById(view12->id())); + embedded->GetWindowById(window12->id())); } } namespace { -class VisibilityChangeObserver : public ViewObserver { +class VisibilityChangeObserver : public WindowObserver { public: - explicit VisibilityChangeObserver(View* view) : view_(view) { - view_->AddObserver(this); + explicit VisibilityChangeObserver(Window* window) : window_(window) { + window_->AddObserver(this); } - ~VisibilityChangeObserver() override { view_->RemoveObserver(this); } + ~VisibilityChangeObserver() override { window_->RemoveObserver(this); } private: - // Overridden from ViewObserver: - void OnViewVisibilityChanged(View* view) override { - EXPECT_EQ(view, view_); - EXPECT_TRUE(ViewManagerTestBase::QuitRunLoop()); + // Overridden from WindowObserver: + void OnWindowVisibilityChanged(Window* window) override { + EXPECT_EQ(window, window_); + EXPECT_TRUE(WindowServerTestBase::QuitRunLoop()); } - View* view_; + Window* window_; MOJO_DISALLOW_COPY_AND_ASSIGN(VisibilityChangeObserver); }; } // namespace -TEST_F(ViewManagerTest, Visible) { - View* view1 = window_manager()->CreateView(); - view1->SetVisible(true); - window_manager()->GetRoot()->AddChild(view1); +TEST_F(WindowServerTest, Visible) { + Window* window1 = window_manager()->CreateWindow(); + window1->SetVisible(true); + window_manager()->GetRoot()->AddChild(window1); // Embed another app and verify initial state. - ViewTreeConnection* embedded = Embed(view1).connection; + WindowTreeConnection* embedded = Embed(window1).connection; ASSERT_NE(nullptr, embedded); ASSERT_NE(nullptr, embedded->GetRoot()); - View* embedded_root = embedded->GetRoot(); + Window* embedded_root = embedded->GetRoot(); EXPECT_TRUE(embedded_root->visible()); EXPECT_TRUE(embedded_root->IsDrawn()); @@ -457,12 +468,12 @@ // correctly to the embedded app. { VisibilityChangeObserver observer(embedded_root); - view1->SetVisible(false); - ASSERT_TRUE(ViewManagerTestBase::DoRunLoopWithTimeout()); + window1->SetVisible(false); + ASSERT_TRUE(WindowServerTestBase::DoRunLoopWithTimeout()); } - EXPECT_FALSE(view1->visible()); - EXPECT_FALSE(view1->IsDrawn()); + EXPECT_FALSE(window1->visible()); + EXPECT_FALSE(window1->IsDrawn()); EXPECT_FALSE(embedded_root->visible()); EXPECT_FALSE(embedded_root->IsDrawn()); @@ -470,12 +481,12 @@ // Make the node visible again. { VisibilityChangeObserver observer(embedded_root); - view1->SetVisible(true); - ASSERT_TRUE(ViewManagerTestBase::DoRunLoopWithTimeout()); + window1->SetVisible(true); + ASSERT_TRUE(WindowServerTestBase::DoRunLoopWithTimeout()); } - EXPECT_TRUE(view1->visible()); - EXPECT_TRUE(view1->IsDrawn()); + EXPECT_TRUE(window1->visible()); + EXPECT_TRUE(window1->IsDrawn()); EXPECT_TRUE(embedded_root->visible()); EXPECT_TRUE(embedded_root->IsDrawn()); @@ -483,37 +494,37 @@ namespace { -class DrawnChangeObserver : public ViewObserver { +class DrawnChangeObserver : public WindowObserver { public: - explicit DrawnChangeObserver(View* view) : view_(view) { - view_->AddObserver(this); + explicit DrawnChangeObserver(Window* window) : window_(window) { + window_->AddObserver(this); } - ~DrawnChangeObserver() override { view_->RemoveObserver(this); } + ~DrawnChangeObserver() override { window_->RemoveObserver(this); } private: - // Overridden from ViewObserver: - void OnViewDrawnChanged(View* view) override { - EXPECT_EQ(view, view_); - EXPECT_TRUE(ViewManagerTestBase::QuitRunLoop()); + // Overridden from WindowObserver: + void OnWindowDrawnChanged(Window* window) override { + EXPECT_EQ(window, window_); + EXPECT_TRUE(WindowServerTestBase::QuitRunLoop()); } - View* view_; + Window* window_; MOJO_DISALLOW_COPY_AND_ASSIGN(DrawnChangeObserver); }; } // namespace -TEST_F(ViewManagerTest, Drawn) { - View* view1 = window_manager()->CreateView(); - view1->SetVisible(true); - window_manager()->GetRoot()->AddChild(view1); +TEST_F(WindowServerTest, Drawn) { + Window* window1 = window_manager()->CreateWindow(); + window1->SetVisible(true); + window_manager()->GetRoot()->AddChild(window1); // Embed another app and verify initial state. - ViewTreeConnection* embedded = Embed(view1).connection; + WindowTreeConnection* embedded = Embed(window1).connection; ASSERT_NE(nullptr, embedded); ASSERT_NE(nullptr, embedded->GetRoot()); - View* embedded_root = embedded->GetRoot(); + Window* embedded_root = embedded->GetRoot(); EXPECT_TRUE(embedded_root->visible()); EXPECT_TRUE(embedded_root->IsDrawn()); @@ -525,64 +536,66 @@ ASSERT_TRUE(DoRunLoopWithTimeout()); } - EXPECT_TRUE(view1->visible()); - EXPECT_FALSE(view1->IsDrawn()); + EXPECT_TRUE(window1->visible()); + EXPECT_FALSE(window1->IsDrawn()); EXPECT_TRUE(embedded_root->visible()); EXPECT_FALSE(embedded_root->IsDrawn()); } -// TODO(beng): tests for view event dispatcher. -// - verify that we see events for all views. +// TODO(beng): tests for window event dispatcher. +// - verify that we see events for all windows. namespace { -class FocusChangeObserver : public ViewObserver { +class FocusChangeObserver : public WindowObserver { public: - explicit FocusChangeObserver(View* view) - : view_(view), last_gained_focus_(nullptr), last_lost_focus_(nullptr) { - view_->AddObserver(this); + explicit FocusChangeObserver(Window* window) + : window_(window), + last_gained_focus_(nullptr), + last_lost_focus_(nullptr) { + window_->AddObserver(this); } - ~FocusChangeObserver() override { view_->RemoveObserver(this); } + ~FocusChangeObserver() override { window_->RemoveObserver(this); } - View* last_gained_focus() { return last_gained_focus_; } + Window* last_gained_focus() { return last_gained_focus_; } - View* last_lost_focus() { return last_lost_focus_; } + Window* last_lost_focus() { return last_lost_focus_; } private: - // Overridden from ViewObserver. - void OnViewFocusChanged(View* gained_focus, View* lost_focus) override { + // Overridden from WindowObserver. + void OnWindowFocusChanged(Window* gained_focus, Window* lost_focus) override { EXPECT_TRUE(!gained_focus || gained_focus->HasFocus()); EXPECT_FALSE(lost_focus && lost_focus->HasFocus()); last_gained_focus_ = gained_focus; last_lost_focus_ = lost_focus; - EXPECT_TRUE(ViewManagerTestBase::QuitRunLoop()); + EXPECT_TRUE(WindowServerTestBase::QuitRunLoop()); } - View* view_; - View* last_gained_focus_; - View* last_lost_focus_; + Window* window_; + Window* last_gained_focus_; + Window* last_lost_focus_; MOJO_DISALLOW_COPY_AND_ASSIGN(FocusChangeObserver); }; } // namespace -TEST_F(ViewManagerTest, Focus) { - View* view1 = window_manager()->CreateView(); - view1->SetVisible(true); - window_manager()->GetRoot()->AddChild(view1); +TEST_F(WindowServerTest, Focus) { + Window* window1 = window_manager()->CreateWindow(); + window1->SetVisible(true); + window_manager()->GetRoot()->AddChild(window1); - ViewTreeConnection* embedded = Embed(view1).connection; + WindowTreeConnection* embedded = Embed(window1).connection; ASSERT_NE(nullptr, embedded); - View* view11 = embedded->CreateView(); - view11->SetVisible(true); - embedded->GetRoot()->AddChild(view11); + Window* window11 = embedded->CreateWindow(); + window11->SetVisible(true); + embedded->GetRoot()->AddChild(window11); - // TODO(alhaad): Figure out why switching focus between views from different + // TODO(alhaad): Figure out why switching focus between windows from different // connections is causing the tests to crash and add tests for that. { - View* embedded_root = embedded->GetRoot(); + Window* embedded_root = embedded->GetRoot(); FocusChangeObserver observer(embedded_root); embedded_root->SetFocus(); ASSERT_TRUE(DoRunLoopWithTimeout()); @@ -590,56 +603,57 @@ EXPECT_EQ(embedded_root->id(), observer.last_gained_focus()->id()); } { - FocusChangeObserver observer(view11); - view11->SetFocus(); + FocusChangeObserver observer(window11); + window11->SetFocus(); ASSERT_TRUE(DoRunLoopWithTimeout()); ASSERT_NE(nullptr, observer.last_gained_focus()); ASSERT_NE(nullptr, observer.last_lost_focus()); - EXPECT_EQ(view11->id(), observer.last_gained_focus()->id()); + EXPECT_EQ(window11->id(), observer.last_gained_focus()->id()); EXPECT_EQ(embedded->GetRoot()->id(), observer.last_lost_focus()->id()); } { - // Add an observer on the View that loses focus, and make sure the observer + // Add an observer on the Window that loses focus, and make sure the + // observer // sees the right values. - FocusChangeObserver observer(view11); + FocusChangeObserver observer(window11); embedded->GetRoot()->SetFocus(); ASSERT_TRUE(DoRunLoopWithTimeout()); ASSERT_NE(nullptr, observer.last_gained_focus()); ASSERT_NE(nullptr, observer.last_lost_focus()); - EXPECT_EQ(view11->id(), observer.last_lost_focus()->id()); + EXPECT_EQ(window11->id(), observer.last_lost_focus()->id()); EXPECT_EQ(embedded->GetRoot()->id(), observer.last_gained_focus()->id()); } } namespace { -class DestroyedChangedObserver : public ViewObserver { +class DestroyedChangedObserver : public WindowObserver { public: - DestroyedChangedObserver(ViewManagerTestBase* test, - View* view, + DestroyedChangedObserver(WindowServerTestBase* test, + Window* window, bool* got_destroy) - : test_(test), view_(view), got_destroy_(got_destroy) { - view_->AddObserver(this); + : test_(test), window_(window), got_destroy_(got_destroy) { + window_->AddObserver(this); } ~DestroyedChangedObserver() override { - if (view_) - view_->RemoveObserver(this); + if (window_) + window_->RemoveObserver(this); } private: - // Overridden from ViewObserver: - void OnViewDestroyed(View* view) override { - EXPECT_EQ(view, view_); - view_->RemoveObserver(this); + // Overridden from WindowObserver: + void OnWindowDestroyed(Window* window) override { + EXPECT_EQ(window, window_); + window_->RemoveObserver(this); *got_destroy_ = true; - view_ = nullptr; + window_ = nullptr; - // We should always get OnViewDestroyed() before OnConnectionLost(). - EXPECT_FALSE(test_->view_tree_connection_destroyed()); + // We should always get OnWindowDestroyed() before OnConnectionLost(). + EXPECT_FALSE(test_->window_tree_connection_destroyed()); } - ViewManagerTestBase* test_; - View* view_; + WindowServerTestBase* test_; + Window* window_; bool* got_destroy_; MOJO_DISALLOW_COPY_AND_ASSIGN(DestroyedChangedObserver); @@ -647,73 +661,73 @@ } // namespace -// Verifies deleting a ViewManager sends the right notifications. -TEST_F(ViewManagerTest, DeleteViewManager) { - View* view = window_manager()->CreateView(); - ASSERT_NE(nullptr, view); - view->SetVisible(true); - window_manager()->GetRoot()->AddChild(view); - ViewTreeConnection* connection = Embed(view).connection; +// Verifies deleting a WindowServer sends the right notifications. +TEST_F(WindowServerTest, DeleteWindowServer) { + Window* window = window_manager()->CreateWindow(); + ASSERT_NE(nullptr, window); + window->SetVisible(true); + window_manager()->GetRoot()->AddChild(window); + WindowTreeConnection* connection = Embed(window).connection; ASSERT_TRUE(connection); bool got_destroy = false; DestroyedChangedObserver observer(this, connection->GetRoot(), &got_destroy); delete connection; - EXPECT_TRUE(view_tree_connection_destroyed()); + EXPECT_TRUE(window_tree_connection_destroyed()); EXPECT_TRUE(got_destroy); } -// Verifies two Embed()s in the same view trigger deletion of the first -// ViewManager. -TEST_F(ViewManagerTest, DisconnectTriggersDelete) { - View* view = window_manager()->CreateView(); - ASSERT_NE(nullptr, view); - view->SetVisible(true); - window_manager()->GetRoot()->AddChild(view); - ViewTreeConnection* connection = Embed(view).connection; +// Verifies two Embed()s in the same window trigger deletion of the first +// WindowServer. +TEST_F(WindowServerTest, DisconnectTriggersDelete) { + Window* window = window_manager()->CreateWindow(); + ASSERT_NE(nullptr, window); + window->SetVisible(true); + window_manager()->GetRoot()->AddChild(window); + WindowTreeConnection* connection = Embed(window).connection; EXPECT_NE(connection, window_manager()); - View* embedded_view = connection->CreateView(); + Window* embedded_window = connection->CreateWindow(); // Embed again, this should trigger disconnect and deletion of connection. bool got_destroy; - DestroyedChangedObserver observer(this, embedded_view, &got_destroy); - EXPECT_FALSE(view_tree_connection_destroyed()); - Embed(view); - EXPECT_TRUE(view_tree_connection_destroyed()); + DestroyedChangedObserver observer(this, embedded_window, &got_destroy); + EXPECT_FALSE(window_tree_connection_destroyed()); + Embed(window); + EXPECT_TRUE(window_tree_connection_destroyed()); } -class ViewRemovedFromParentObserver : public ViewObserver { +class WindowRemovedFromParentObserver : public WindowObserver { public: - explicit ViewRemovedFromParentObserver(View* view) - : view_(view), was_removed_(false) { - view_->AddObserver(this); + explicit WindowRemovedFromParentObserver(Window* window) + : window_(window), was_removed_(false) { + window_->AddObserver(this); } - ~ViewRemovedFromParentObserver() override { view_->RemoveObserver(this); } + ~WindowRemovedFromParentObserver() override { window_->RemoveObserver(this); } bool was_removed() const { return was_removed_; } private: - // Overridden from ViewObserver: + // Overridden from WindowObserver: void OnTreeChanged(const TreeChangeParams& params) override { - if (params.target == view_ && !params.new_parent) + if (params.target == window_ && !params.new_parent) was_removed_ = true; } - View* view_; + Window* window_; bool was_removed_; - MOJO_DISALLOW_COPY_AND_ASSIGN(ViewRemovedFromParentObserver); + MOJO_DISALLOW_COPY_AND_ASSIGN(WindowRemovedFromParentObserver); }; -TEST_F(ViewManagerTest, EmbedRemovesChildren) { - View* view1 = window_manager()->CreateView(); - View* view2 = window_manager()->CreateView(); - window_manager()->GetRoot()->AddChild(view1); - view1->AddChild(view2); +TEST_F(WindowServerTest, EmbedRemovesChildren) { + Window* window1 = window_manager()->CreateWindow(); + Window* window2 = window_manager()->CreateWindow(); + window_manager()->GetRoot()->AddChild(window1); + window1->AddChild(window2); - ViewRemovedFromParentObserver observer(view2); - view1->Embed(ConnectToApplicationAndGetViewManagerClient()); + WindowRemovedFromParentObserver observer(window2); + window1->Embed(ConnectToApplicationAndGetWindowServerClient()); EXPECT_TRUE(observer.was_removed()); - EXPECT_EQ(nullptr, view2->parent()); - EXPECT_TRUE(view1->children().empty()); + EXPECT_EQ(nullptr, window2->parent()); + EXPECT_TRUE(window1->children().empty()); // Run the message loop so the Embed() call above completes. Without this // we may end up reconnecting to the test and rerunning the test, which is @@ -723,10 +737,10 @@ namespace { -class DestroyObserver : public ViewObserver { +class DestroyObserver : public WindowObserver { public: - DestroyObserver(ViewManagerTestBase* test, - ViewTreeConnection* connection, + DestroyObserver(WindowServerTestBase* test, + WindowTreeConnection* connection, bool* got_destroy) : test_(test), got_destroy_(got_destroy) { connection->GetRoot()->AddObserver(this); @@ -734,18 +748,19 @@ ~DestroyObserver() override {} private: - // Overridden from ViewObserver: - void OnViewDestroyed(View* view) override { + // Overridden from WindowObserver: + void OnWindowDestroyed(Window* window) override { *got_destroy_ = true; - view->RemoveObserver(this); + window->RemoveObserver(this); - // We should always get OnViewDestroyed() before OnViewManagerDestroyed(). - EXPECT_FALSE(test_->view_tree_connection_destroyed()); + // We should always get OnWindowDestroyed() before + // OnWindowManagerDestroyed(). + EXPECT_FALSE(test_->window_tree_connection_destroyed()); - EXPECT_TRUE(ViewManagerTestBase::QuitRunLoop()); + EXPECT_TRUE(WindowServerTestBase::QuitRunLoop()); } - ViewManagerTestBase* test_; + WindowServerTestBase* test_; bool* got_destroy_; MOJO_DISALLOW_COPY_AND_ASSIGN(DestroyObserver); @@ -753,59 +768,59 @@ } // namespace -// Verifies deleting a View that is the root of another connection notifies -// observers in the right order (OnViewDestroyed() before -// OnViewManagerDestroyed()). -TEST_F(ViewManagerTest, ViewManagerDestroyedAfterRootObserver) { - View* embed_view = window_manager()->CreateView(); - window_manager()->GetRoot()->AddChild(embed_view); +// Verifies deleting a Window that is the root of another connection notifies +// observers in the right order (OnWindowDestroyed() before +// OnWindowManagerDestroyed()). +TEST_F(WindowServerTest, WindowServerDestroyedAfterRootObserver) { + Window* embed_window = window_manager()->CreateWindow(); + window_manager()->GetRoot()->AddChild(embed_window); - ViewTreeConnection* embedded_connection = Embed(embed_view).connection; + WindowTreeConnection* embedded_connection = Embed(embed_window).connection; bool got_destroy = false; DestroyObserver observer(this, embedded_connection, &got_destroy); - // Delete the view |embedded_connection| is embedded in. This is async, + // Delete the window |embedded_connection| is embedded in. This is async, // but will eventually trigger deleting |embedded_connection|. - embed_view->Destroy(); + embed_window->Destroy(); EXPECT_TRUE(DoRunLoopWithTimeout()); EXPECT_TRUE(got_destroy); } -// Verifies an embed root sees views created beneath it from another +// Verifies an embed root sees windows created beneath it from another // connection. -TEST_F(ViewManagerTest, EmbedRootSeesHierarchyChanged) { - View* embed_view = window_manager()->CreateView(); - window_manager()->GetRoot()->AddChild(embed_view); +TEST_F(WindowServerTest, EmbedRootSeesHierarchyChanged) { + Window* embed_window = window_manager()->CreateWindow(); + window_manager()->GetRoot()->AddChild(embed_window); - ViewTreeConnection* vm2 = - Embed(embed_view, mojo::ViewTree::ACCESS_POLICY_EMBED_ROOT).connection; - View* vm2_v1 = vm2->CreateView(); + WindowTreeConnection* vm2 = + Embed(embed_window, mojo::ViewTree::ACCESS_POLICY_EMBED_ROOT).connection; + Window* vm2_v1 = vm2->CreateWindow(); vm2->GetRoot()->AddChild(vm2_v1); - ViewTreeConnection* vm3 = Embed(vm2_v1).connection; - View* vm3_v1 = vm3->CreateView(); + WindowTreeConnection* vm3 = Embed(vm2_v1).connection; + Window* vm3_v1 = vm3->CreateWindow(); vm3->GetRoot()->AddChild(vm3_v1); // As |vm2| is an embed root it should get notified about |vm3_v1|. ASSERT_TRUE(WaitForTreeSizeToMatch(vm2_v1, 2)); } -TEST_F(ViewManagerTest, EmbedFromEmbedRoot) { - View* embed_view = window_manager()->CreateView(); - window_manager()->GetRoot()->AddChild(embed_view); +TEST_F(WindowServerTest, EmbedFromEmbedRoot) { + Window* embed_window = window_manager()->CreateWindow(); + window_manager()->GetRoot()->AddChild(embed_window); - // Give the connection embedded at |embed_view| embed root powers. + // Give the connection embedded at |embed_window| embed root powers. const EmbedResult result1 = - Embed(embed_view, mojo::ViewTree::ACCESS_POLICY_EMBED_ROOT); - ViewTreeConnection* vm2 = result1.connection; + Embed(embed_window, mojo::ViewTree::ACCESS_POLICY_EMBED_ROOT); + WindowTreeConnection* vm2 = result1.connection; EXPECT_EQ(result1.connection_id, vm2->GetConnectionId()); - View* vm2_v1 = vm2->CreateView(); + Window* vm2_v1 = vm2->CreateWindow(); vm2->GetRoot()->AddChild(vm2_v1); const EmbedResult result2 = Embed(vm2_v1); - ViewTreeConnection* vm3 = result2.connection; + WindowTreeConnection* vm3 = result2.connection; EXPECT_EQ(result2.connection_id, vm3->GetConnectionId()); - View* vm3_v1 = vm3->CreateView(); + Window* vm3_v1 = vm3->CreateWindow(); vm3->GetRoot()->AddChild(vm3_v1); // Embed from v3, the callback should not get the connection id as vm3 is not @@ -820,7 +835,7 @@ // Embed() from vm2 in vm3_v1. This is allowed as vm2 is an embed root, and // further the callback should see the connection id. ASSERT_EQ(1u, vm2_v1->children().size()); - View* vm3_v1_in_vm2 = vm2_v1->children()[0]; + Window* vm3_v1_in_vm2 = vm2_v1->children()[0]; const EmbedResult result4 = Embed(vm3_v1_in_vm2); ASSERT_TRUE(result4.connection); EXPECT_EQ(result4.connection_id, result4.connection->GetConnectionId());
diff --git a/components/mus/vm/view_tree_apptest.cc b/components/mus/vm/view_tree_apptest.cc index 14c812a5..3f34d10 100644 --- a/components/mus/vm/view_tree_apptest.cc +++ b/components/mus/vm/view_tree_apptest.cc
@@ -316,55 +316,55 @@ tracker()->OnEmbeddedAppDisconnected(view_id); } void OnUnembed() override { tracker()->OnUnembed(); } - void OnViewBoundsChanged(Id view_id, - RectPtr old_bounds, - RectPtr new_bounds) override { + void OnWindowBoundsChanged(Id view_id, + RectPtr old_bounds, + RectPtr new_bounds) override { // The bounds of the root may change during startup on Android at random // times. As this doesn't matter, and shouldn't impact test exepctations, // it is ignored. if (view_id == root_view_id_) return; - tracker()->OnViewBoundsChanged(view_id, old_bounds.Pass(), - new_bounds.Pass()); + tracker()->OnWindowBoundsChanged(view_id, old_bounds.Pass(), + new_bounds.Pass()); } - void OnViewViewportMetricsChanged(ViewportMetricsPtr old_metrics, - ViewportMetricsPtr new_metrics) override { + void OnWindowViewportMetricsChanged(ViewportMetricsPtr old_metrics, + ViewportMetricsPtr new_metrics) override { // Don't track the metrics as they are available at an indeterministic time // on Android. } - void OnViewHierarchyChanged(Id view, - Id new_parent, - Id old_parent, - Array<ViewDataPtr> views) override { - tracker()->OnViewHierarchyChanged(view, new_parent, old_parent, - views.Pass()); + void OnWindowHierarchyChanged(Id view, + Id new_parent, + Id old_parent, + Array<ViewDataPtr> views) override { + tracker()->OnWindowHierarchyChanged(view, new_parent, old_parent, + views.Pass()); } - void OnViewReordered(Id view_id, - Id relative_view_id, - OrderDirection direction) override { - tracker()->OnViewReordered(view_id, relative_view_id, direction); + void OnWindowReordered(Id view_id, + Id relative_view_id, + OrderDirection direction) override { + tracker()->OnWindowReordered(view_id, relative_view_id, direction); } - void OnViewDeleted(Id view) override { tracker()->OnViewDeleted(view); } - void OnViewVisibilityChanged(uint32_t view, bool visible) override { - tracker()->OnViewVisibilityChanged(view, visible); + void OnWindowDeleted(Id view) override { tracker()->OnWindowDeleted(view); } + void OnWindowVisibilityChanged(uint32_t view, bool visible) override { + tracker()->OnWindowVisibilityChanged(view, visible); } - void OnViewDrawnStateChanged(uint32_t view, bool drawn) override { - tracker()->OnViewDrawnStateChanged(view, drawn); + void OnWindowDrawnStateChanged(uint32_t view, bool drawn) override { + tracker()->OnWindowDrawnStateChanged(view, drawn); } - void OnViewInputEvent(Id view_id, - EventPtr event, - const Callback<void()>& callback) override { + void OnWindowInputEvent(Id view_id, + EventPtr event, + const Callback<void()>& callback) override { // Don't log input events as none of the tests care about them and they // may come in at random points. callback.Run(); } - void OnViewSharedPropertyChanged(uint32_t view, - const String& name, - Array<uint8_t> new_data) override { - tracker_.OnViewSharedPropertyChanged(view, name, new_data.Pass()); + void OnWindowSharedPropertyChanged(uint32_t view, + const String& name, + Array<uint8_t> new_data) override { + tracker_.OnWindowSharedPropertyChanged(view, name, new_data.Pass()); } // TODO(sky): add testing coverage. - void OnViewFocused(uint32_t focused_view_id) override {} + void OnWindowFocused(uint32_t focused_view_id) override {} TestChangeTracker tracker_; @@ -534,8 +534,9 @@ vm_client1_.reset(new TestViewTreeClientImpl(application_impl())); vm_client1_->Bind(GetProxy(&tree_client_ptr)); - factory->CreateViewTreeHost(GetProxy(&host_), mojo::ViewTreeHostClientPtr(), - tree_client_ptr.Pass()); + factory->CreateWindowTreeHost(GetProxy(&host_), + mojo::ViewTreeHostClientPtr(), + tree_client_ptr.Pass()); // Next we should get an embed call on the "window manager" client. vm_client1_->WaitForIncomingMethodCall();
diff --git a/components/mus/vm/view_tree_host_impl.cc b/components/mus/vm/view_tree_host_impl.cc index 6dc9c3e..5fdbdc57 100644 --- a/components/mus/vm/view_tree_host_impl.cc +++ b/components/mus/vm/view_tree_host_impl.cc
@@ -111,9 +111,9 @@ connection_manager_->GetConnectionWithRoot(target->id()); if (!connection) connection = connection_manager_->GetConnection(target->id().connection_id); - connection->client()->OnViewInputEvent(ViewIdToTransportId(target->id()), - event.Pass(), - base::Bind(&base::DoNothing)); + connection->client()->OnWindowInputEvent(ViewIdToTransportId(target->id()), + event.Pass(), + base::Bind(&base::DoNothing)); } void ViewTreeHostImpl::SetSize(mojo::SizePtr size) {
diff --git a/components/mus/vm/view_tree_impl.cc b/components/mus/vm/view_tree_impl.cc index 794f56b9..40e2c07 100644 --- a/components/mus/vm/view_tree_impl.cc +++ b/components/mus/vm/view_tree_impl.cc
@@ -181,16 +181,17 @@ bool originated_change) { if (originated_change || !IsViewKnown(view)) return; - client()->OnViewBoundsChanged(ViewIdToTransportId(view->id()), - Rect::From(old_bounds), Rect::From(new_bounds)); + client()->OnWindowBoundsChanged(ViewIdToTransportId(view->id()), + Rect::From(old_bounds), + Rect::From(new_bounds)); } void ViewTreeImpl::ProcessViewportMetricsChanged( const mojo::ViewportMetrics& old_metrics, const mojo::ViewportMetrics& new_metrics, bool originated_change) { - client()->OnViewViewportMetricsChanged(old_metrics.Clone(), - new_metrics.Clone()); + client()->OnWindowViewportMetricsChanged(old_metrics.Clone(), + new_metrics.Clone()); } void ViewTreeImpl::ProcessWillChangeViewHierarchy(const ServerView* view, @@ -220,8 +221,8 @@ if (new_data) data = Array<uint8_t>::From(*new_data); - client()->OnViewSharedPropertyChanged(ViewIdToTransportId(view->id()), - String(name), data.Pass()); + client()->OnWindowSharedPropertyChanged(ViewIdToTransportId(view->id()), + String(name), data.Pass()); } void ViewTreeImpl::ProcessViewHierarchyChanged(const ServerView* view, @@ -249,7 +250,7 @@ GetUnknownViewsFrom(view, &to_send); const ViewId new_parent_id(new_parent ? new_parent->id() : ViewId()); const ViewId old_parent_id(old_parent ? old_parent->id() : ViewId()); - client()->OnViewHierarchyChanged( + client()->OnWindowHierarchyChanged( ViewIdToTransportId(view->id()), ViewIdToTransportId(new_parent_id), ViewIdToTransportId(old_parent_id), ViewsToViewDatas(to_send)); connection_manager_->OnConnectionMessagedClient(id_); @@ -262,9 +263,9 @@ if (originated_change || !IsViewKnown(view) || !IsViewKnown(relative_view)) return; - client()->OnViewReordered(ViewIdToTransportId(view->id()), - ViewIdToTransportId(relative_view->id()), - direction); + client()->OnWindowReordered(ViewIdToTransportId(view->id()), + ViewIdToTransportId(relative_view->id()), + direction); } void ViewTreeImpl::ProcessViewDeleted(const ViewId& view, @@ -281,7 +282,7 @@ return; if (in_known) { - client()->OnViewDeleted(ViewIdToTransportId(view)); + client()->OnWindowDeleted(ViewIdToTransportId(view)); connection_manager_->OnConnectionMessagedClient(id_); } } @@ -292,8 +293,8 @@ return; if (IsViewKnown(view)) { - client()->OnViewVisibilityChanged(ViewIdToTransportId(view->id()), - !view->visible()); + client()->OnWindowVisibilityChanged(ViewIdToTransportId(view->id()), + !view->visible()); return; } @@ -314,8 +315,8 @@ const ServerView* view = new_focused_view ? access_policy_->GetViewForFocusChange(new_focused_view) : nullptr; - client()->OnViewFocused(view ? ViewIdToTransportId(view->id()) - : ViewIdToTransportId(ViewId())); + client()->OnWindowFocused(view ? ViewIdToTransportId(view->id()) + : ViewIdToTransportId(ViewId())); } bool ViewTreeImpl::IsViewKnown(const ServerView* view) const { @@ -391,7 +392,7 @@ return; client()->OnUnembed(); - client()->OnViewDeleted(ViewIdToTransportId(root_id)); + client()->OnWindowDeleted(ViewIdToTransportId(root_id)); connection_manager_->OnConnectionMessagedClient(id_); // This connection no longer knows about the view. Unparent any views that @@ -458,8 +459,8 @@ const ServerView* root = GetView(*root_); DCHECK(root); if (view->Contains(root) && (new_drawn_value != root->IsDrawn())) { - client()->OnViewDrawnStateChanged(ViewIdToTransportId(root->id()), - new_drawn_value); + client()->OnWindowDrawnStateChanged(ViewIdToTransportId(root->id()), + new_drawn_value); } } @@ -609,7 +610,7 @@ mojo::InterfaceRequest<mojo::Surface> surface, mojo::SurfaceClientPtr client) { ServerView* view = GetView(ViewIdFromTransportId(view_id)); - const bool success = view && access_policy_->CanSetViewSurfaceId(view); + const bool success = view && access_policy_->CanSetWindowSurfaceId(view); if (!success) return; view->Bind(surface.Pass(), client.Pass());
diff --git a/components/mus/vm/view_tree_unittest.cc b/components/mus/vm/view_tree_unittest.cc index a775d039..352625c 100644 --- a/components/mus/vm/view_tree_unittest.cc +++ b/components/mus/vm/view_tree_unittest.cc
@@ -61,47 +61,50 @@ tracker_.OnEmbeddedAppDisconnected(view); } void OnUnembed() override { tracker_.OnUnembed(); } - void OnViewBoundsChanged(uint32_t view, - mojo::RectPtr old_bounds, - mojo::RectPtr new_bounds) override { - tracker_.OnViewBoundsChanged(view, old_bounds.Pass(), new_bounds.Pass()); + void OnWindowBoundsChanged(uint32_t view, + mojo::RectPtr old_bounds, + mojo::RectPtr new_bounds) override { + tracker_.OnWindowBoundsChanged(view, old_bounds.Pass(), new_bounds.Pass()); } - void OnViewViewportMetricsChanged( + void OnWindowViewportMetricsChanged( mojo::ViewportMetricsPtr old_metrics, mojo::ViewportMetricsPtr new_metrics) override { - tracker_.OnViewViewportMetricsChanged(old_metrics.Pass(), - new_metrics.Pass()); + tracker_.OnWindowViewportMetricsChanged(old_metrics.Pass(), + new_metrics.Pass()); } - void OnViewHierarchyChanged(uint32_t view, - uint32_t new_parent, - uint32_t old_parent, - Array<ViewDataPtr> views) override { - tracker_.OnViewHierarchyChanged(view, new_parent, old_parent, views.Pass()); + void OnWindowHierarchyChanged(uint32_t view, + uint32_t new_parent, + uint32_t old_parent, + Array<ViewDataPtr> views) override { + tracker_.OnWindowHierarchyChanged(view, new_parent, old_parent, + views.Pass()); } - void OnViewReordered(uint32_t view_id, - uint32_t relative_view_id, - mojo::OrderDirection direction) override { - tracker_.OnViewReordered(view_id, relative_view_id, direction); + void OnWindowReordered(uint32_t view_id, + uint32_t relative_view_id, + mojo::OrderDirection direction) override { + tracker_.OnWindowReordered(view_id, relative_view_id, direction); } - void OnViewDeleted(uint32_t view) override { tracker_.OnViewDeleted(view); } - void OnViewVisibilityChanged(uint32_t view, bool visible) override { - tracker_.OnViewVisibilityChanged(view, visible); + void OnWindowDeleted(uint32_t view) override { + tracker_.OnWindowDeleted(view); } - void OnViewDrawnStateChanged(uint32_t view, bool drawn) override { - tracker_.OnViewDrawnStateChanged(view, drawn); + void OnWindowVisibilityChanged(uint32_t view, bool visible) override { + tracker_.OnWindowVisibilityChanged(view, visible); } - void OnViewSharedPropertyChanged(uint32_t view, - const String& name, - Array<uint8_t> new_data) override { - tracker_.OnViewSharedPropertyChanged(view, name, new_data.Pass()); + void OnWindowDrawnStateChanged(uint32_t view, bool drawn) override { + tracker_.OnWindowDrawnStateChanged(view, drawn); } - void OnViewInputEvent(uint32_t view, - mojo::EventPtr event, - const mojo::Callback<void()>& callback) override { - tracker_.OnViewInputEvent(view, event.Pass()); + void OnWindowSharedPropertyChanged(uint32_t view, + const String& name, + Array<uint8_t> new_data) override { + tracker_.OnWindowSharedPropertyChanged(view, name, new_data.Pass()); } - void OnViewFocused(uint32_t focused_view_id) override { - tracker_.OnViewFocused(focused_view_id); + void OnWindowInputEvent(uint32_t view, + mojo::EventPtr event, + const mojo::Callback<void()>& callback) override { + tracker_.OnWindowInputEvent(view, event.Pass()); + } + void OnWindowFocused(uint32_t focused_view_id) override { + tracker_.OnWindowFocused(focused_view_id); } TestChangeTracker tracker_;
diff --git a/components/mus/vm/window_manager_access_policy.cc b/components/mus/vm/window_manager_access_policy.cc index a7da4972..6cfb6202 100644 --- a/components/mus/vm/window_manager_access_policy.cc +++ b/components/mus/vm/window_manager_access_policy.cc
@@ -61,7 +61,7 @@ (view->GetRoot() == view); } -bool WindowManagerAccessPolicy::CanSetViewSurfaceId( +bool WindowManagerAccessPolicy::CanSetWindowSurfaceId( const ServerView* view) const { if (delegate_->IsViewRootOfAnotherConnectionForAccessPolicy(view)) return false;
diff --git a/components/mus/vm/window_manager_access_policy.h b/components/mus/vm/window_manager_access_policy.h index 78f9513..b08946b6 100644 --- a/components/mus/vm/window_manager_access_policy.h +++ b/components/mus/vm/window_manager_access_policy.h
@@ -30,7 +30,7 @@ bool CanDescendIntoViewForViewTree(const ServerView* view) const override; bool CanEmbed(const ServerView* view, uint32_t policy_bitmask) const override; bool CanChangeViewVisibility(const ServerView* view) const override; - bool CanSetViewSurfaceId(const ServerView* view) const override; + bool CanSetWindowSurfaceId(const ServerView* view) const override; bool CanSetViewBounds(const ServerView* view) const override; bool CanSetViewProperties(const ServerView* view) const override; bool CanSetViewTextInputState(const ServerView* view) const override;
diff --git a/components/pdf_viewer/pdf_viewer.cc b/components/pdf_viewer/pdf_viewer.cc index 01336a3d..b1c11c7b 100644 --- a/components/pdf_viewer/pdf_viewer.cc +++ b/components/pdf_viewer/pdf_viewer.cc
@@ -7,11 +7,11 @@ #include "base/containers/hash_tables.h" #include "base/memory/scoped_ptr.h" #include "components/mus/public/cpp/types.h" -#include "components/mus/public/cpp/view.h" -#include "components/mus/public/cpp/view_observer.h" -#include "components/mus/public/cpp/view_surface.h" -#include "components/mus/public/cpp/view_tree_connection.h" -#include "components/mus/public/cpp/view_tree_delegate.h" +#include "components/mus/public/cpp/window.h" +#include "components/mus/public/cpp/window_observer.h" +#include "components/mus/public/cpp/window_surface.h" +#include "components/mus/public/cpp/window_tree_connection.h" +#include "components/mus/public/cpp/window_tree_delegate.h" #include "components/mus/public/interfaces/compositor_frame.mojom.h" #include "components/mus/public/interfaces/gpu.mojom.h" #include "components/mus/public/interfaces/surface_id.mojom.h" @@ -58,7 +58,7 @@ // BitmapUploader is useful if you want to draw a bitmap or color in a View. class BitmapUploader : public mojo::SurfaceClient { public: - explicit BitmapUploader(mus::View* view) + explicit BitmapUploader(mus::Window* view) : view_(view), color_(g_transparent_color), width_(0), @@ -289,9 +289,9 @@ } } - mus::View* view_; + mus::Window* view_; mojo::GpuPtr gpu_service_; - scoped_ptr<mus::ViewSurface> surface_; + scoped_ptr<mus::WindowSurface> surface_; MojoGLES2Context gles2_context_; mojo::Size size_; @@ -311,7 +311,7 @@ class EmbedderData { public: - EmbedderData(mojo::Shell* shell, mus::View* root) : bitmap_uploader_(root) { + EmbedderData(mojo::Shell* shell, mus::Window* root) : bitmap_uploader_(root) { bitmap_uploader_.Init(shell); bitmap_uploader_.SetColor(g_background_color); } @@ -325,8 +325,8 @@ }; class PDFView : public mojo::ApplicationDelegate, - public mus::ViewTreeDelegate, - public mus::ViewObserver, + public mus::WindowTreeDelegate, + public mus::WindowObserver, public mojo::InterfaceFactory<mojo::ViewTreeClient> { public: PDFView(mojo::InterfaceRequest<mojo::Application> request, @@ -354,8 +354,8 @@ return true; } - // Overridden from ViewTreeDelegate: - void OnEmbed(mus::View* root) override { + // Overridden from WindowTreeDelegate: + void OnEmbed(mus::Window* root) override { DCHECK(embedder_for_roots_.find(root) == embedder_for_roots_.end()); root->AddObserver(this); EmbedderData* embedder_data = new EmbedderData(app_.shell(), root); @@ -363,17 +363,18 @@ DrawBitmap(embedder_data); } - void OnConnectionLost(mus::ViewTreeConnection* connection) override {} + void OnConnectionLost(mus::WindowTreeConnection* connection) override {} - // Overridden from ViewObserver: - void OnViewBoundsChanged(mus::View* view, - const mojo::Rect& old_bounds, - const mojo::Rect& new_bounds) override { + // Overridden from WindowObserver: + void OnWindowBoundsChanged(mus::Window* view, + const mojo::Rect& old_bounds, + const mojo::Rect& new_bounds) override { DCHECK(embedder_for_roots_.find(view) != embedder_for_roots_.end()); DrawBitmap(embedder_for_roots_[view]); } - void OnViewInputEvent(mus::View* view, const mojo::EventPtr& event) override { + void OnWindowInputEvent(mus::Window* view, + const mojo::EventPtr& event) override { DCHECK(embedder_for_roots_.find(view) != embedder_for_roots_.end()); if (event->key_data && (event->action != mojo::EVENT_TYPE_KEY_PRESSED || @@ -400,7 +401,7 @@ } } - void OnViewDestroyed(mus::View* view) override { + void OnWindowDestroyed(mus::Window* view) override { DCHECK(embedder_for_roots_.find(view) != embedder_for_roots_.end()); const auto& it = embedder_for_roots_.find(view); DCHECK(it != embedder_for_roots_.end()); @@ -414,9 +415,9 @@ void Create( mojo::ApplicationConnection* connection, mojo::InterfaceRequest<mojo::ViewTreeClient> request) override { - mus::ViewTreeConnection::Create( + mus::WindowTreeConnection::Create( this, request.Pass(), - mus::ViewTreeConnection::CreateType::DONT_WAIT_FOR_EMBED); + mus::WindowTreeConnection::CreateType::DONT_WAIT_FOR_EMBED); } void DrawBitmap(EmbedderData* embedder_data) { @@ -465,7 +466,7 @@ int current_page_; int page_count_; FPDF_DOCUMENT doc_; - std::map<mus::View*, EmbedderData*> embedder_for_roots_; + std::map<mus::Window*, EmbedderData*> embedder_for_roots_; DISALLOW_COPY_AND_ASSIGN(PDFView); };
diff --git a/components/plugins/renderer/loadable_plugin_placeholder.cc b/components/plugins/renderer/loadable_plugin_placeholder.cc index 40c4a5a..ed0c1a2 100644 --- a/components/plugins/renderer/loadable_plugin_placeholder.cc +++ b/components/plugins/renderer/loadable_plugin_placeholder.cc
@@ -105,6 +105,7 @@ if (!new_plugin) return; blink::WebPluginContainer* container = plugin()->container(); + CHECK(container->plugin() == plugin()); // Set the new plugin on the container before initializing it. container->setPlugin(new_plugin); // Save the element in case the plugin is removed from the page during
diff --git a/components/policy/BUILD.gn b/components/policy/BUILD.gn index 7b5cca1..b6274b8b 100644 --- a/components/policy/BUILD.gn +++ b/components/policy/BUILD.gn
@@ -24,35 +24,35 @@ # dependencies (GN will do the right thing without this extra target). if (is_component_build) { component("policy_component") { - deps = [ + public_deps = [ "//components/policy/core/browser", "//components/policy/core/common", ] } group("policy_component_browser") { - deps = [ + public_deps = [ ":policy_component", ] } group("policy_component_common") { - deps = [ + public_deps = [ ":policy_component", ] } } else { # Compile to separate libraries. group("policy_component") { - deps = [ + public_deps = [ ":policy_component_browser", ":policy_component_common", ] } component("policy_component_browser") { - deps = [ + public_deps = [ "//components/policy/core/browser", ] } component("policy_component_common") { - deps = [ + public_deps = [ "//components/policy/core/common", ] }
diff --git a/components/resource_provider/public/cpp/resource_loader.cc b/components/resource_provider/public/cpp/resource_loader.cc index 3b6ea168..8b1c116 100644 --- a/components/resource_provider/public/cpp/resource_loader.cc +++ b/components/resource_provider/public/cpp/resource_loader.cc
@@ -6,6 +6,7 @@ #include "base/bind.h" #include "base/files/file.h" +#include "mojo/application/public/cpp/application_impl.h" #include "mojo/application/public/cpp/connect.h" #include "mojo/application/public/interfaces/service_provider.mojom.h" #include "mojo/application/public/interfaces/shell.mojom.h" @@ -23,17 +24,12 @@ } } -ResourceLoader::ResourceLoader(mojo::Shell* shell, +ResourceLoader::ResourceLoader(mojo::ApplicationImpl* app, const std::set<std::string>& paths) : loaded_(false), did_block_(false) { mojo::URLRequestPtr request(mojo::URLRequest::New()); request->url = mojo::String::From("mojo:resource_provider"); - mojo::ServiceProviderPtr resource_provider_service_provider; - shell->ConnectToApplication( - request.Pass(), GetProxy(&resource_provider_service_provider), nullptr, - nullptr, mojo::Shell::ConnectToApplicationCallback()); - mojo::ConnectToService(resource_provider_service_provider.get(), - &resource_provider_); + app->ConnectToService(request.Pass(), &resource_provider_); std::vector<std::string> paths_vector(paths.begin(), paths.end()); resource_provider_->GetResources( mojo::Array<mojo::String>::From(paths_vector),
diff --git a/components/resource_provider/public/cpp/resource_loader.h b/components/resource_provider/public/cpp/resource_loader.h index fae6655f..2b055aa 100644 --- a/components/resource_provider/public/cpp/resource_loader.h +++ b/components/resource_provider/public/cpp/resource_loader.h
@@ -22,7 +22,7 @@ } namespace mojo { -class Shell; +class ApplicationImpl; } namespace resource_provider { @@ -33,7 +33,8 @@ // have been obtained. class ResourceLoader { public: - ResourceLoader(mojo::Shell* shell, const std::set<std::string>& paths); + ResourceLoader(mojo::ApplicationImpl* app, + const std::set<std::string>& paths); ~ResourceLoader(); // Uses WaitForIncomingMessage() to block until the results are available, or
diff --git a/components/resource_provider/resource_provider_apptest.cc b/components/resource_provider/resource_provider_apptest.cc index 5484368..c1f0d07 100644 --- a/components/resource_provider/resource_provider_apptest.cc +++ b/components/resource_provider/resource_provider_apptest.cc
@@ -56,7 +56,7 @@ // resources are returned. The return map maps from the path to the contents // of the file at the specified path. ResourceContentsMap GetResources(const std::set<std::string>& paths) { - ResourceLoader loader(application_impl()->shell(), paths); + ResourceLoader loader(application_impl(), paths); loader.BlockUntilLoaded(); // Load the contents of each of the handles.
diff --git a/components/test_runner/BUILD.gn b/components/test_runner/BUILD.gn index fec5ecd..3c35927 100644 --- a/components/test_runner/BUILD.gn +++ b/components/test_runner/BUILD.gn
@@ -27,6 +27,8 @@ "event_sender.h", "gamepad_controller.cc", "gamepad_controller.h", + "gc_controller.cc", + "gc_controller.h", "mock_color_chooser.cc", "mock_color_chooser.h", "mock_constraints.cc",
diff --git a/components/test_runner/event_sender.cc b/components/test_runner/event_sender.cc index 17a45cf..958fadd6 100644 --- a/components/test_runner/event_sender.cc +++ b/components/test_runner/event_sender.cc
@@ -96,6 +96,12 @@ #else return WebInputEvent::ControlKey; #endif + } else if (!strcmp(characters, "accessKey")) { +#ifdef __APPLE__ + return WebInputEvent::AltKey | WebInputEvent::ControlKey; +#else + return WebInputEvent::AltKey; +#endif } else if (!strcmp(characters, "leftButton")) { return WebInputEvent::LeftButtonDown; } else if (!strcmp(characters, "middleButton")) {
diff --git a/content/shell/renderer/layout_test/gc_controller.cc b/components/test_runner/gc_controller.cc similarity index 95% rename from content/shell/renderer/layout_test/gc_controller.cc rename to components/test_runner/gc_controller.cc index 9741e2b..7d4c85a 100644 --- a/content/shell/renderer/layout_test/gc_controller.cc +++ b/components/test_runner/gc_controller.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 "content/shell/renderer/layout_test/gc_controller.h" +#include "components/test_runner/gc_controller.h" #include "gin/arguments.h" #include "gin/handle.h" @@ -11,7 +11,7 @@ #include "third_party/WebKit/public/web/WebKit.h" #include "v8/include/v8.h" -namespace content { +namespace test_runner { gin::WrapperInfo GCController::kWrapperInfo = {gin::kEmbedderNativeGin}; @@ -69,4 +69,4 @@ v8::Isolate::kMinorGarbageCollection); } -} // namespace content +} // namespace test_runner
diff --git a/content/shell/renderer/layout_test/gc_controller.h b/components/test_runner/gc_controller.h similarity index 77% rename from content/shell/renderer/layout_test/gc_controller.h rename to components/test_runner/gc_controller.h index 4485c1d..2fce5bc 100644 --- a/content/shell/renderer/layout_test/gc_controller.h +++ b/components/test_runner/gc_controller.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 CONTENT_SHELL_RENDERER_LAYOUT_TEST_GC_CONTROLLER_H_ -#define CONTENT_SHELL_RENDERER_LAYOUT_TEST_GC_CONTROLLER_H_ +#ifndef COMPONENTS_TEST_RUNNER_GC_CONTROLLER_H_ +#define COMPONENTS_TEST_RUNNER_GC_CONTROLLER_H_ #include "base/basictypes.h" #include "gin/wrappable.h" @@ -16,7 +16,7 @@ class Arguments; } -namespace content { +namespace test_runner { class GCController : public gin::Wrappable<GCController> { public: @@ -38,6 +38,6 @@ DISALLOW_COPY_AND_ASSIGN(GCController); }; -} // namespace content +} // namespace test_runner -#endif // CONTENT_SHELL_RENDERER_LAYOUT_TEST_GC_CONTROLLER_H_ +#endif // COMPONENTS_TEST_RUNNER_GC_CONTROLLER_H_
diff --git a/components/test_runner/test_interfaces.cc b/components/test_runner/test_interfaces.cc index 614b679..0339ad1 100644 --- a/components/test_runner/test_interfaces.cc +++ b/components/test_runner/test_interfaces.cc
@@ -15,6 +15,7 @@ #include "components/test_runner/app_banner_client.h" #include "components/test_runner/event_sender.h" #include "components/test_runner/gamepad_controller.h" +#include "components/test_runner/gc_controller.h" #include "components/test_runner/test_runner.h" #include "components/test_runner/text_input_controller.h" #include "components/test_runner/web_test_proxy.h" @@ -79,6 +80,7 @@ gamepad_controller_->Install(frame); text_input_controller_->Install(frame); test_runner_->Install(frame); + GCController::Install(frame); } void TestInterfaces::ResetTestHelperControllers() {
diff --git a/components/test_runner/test_runner.gyp b/components/test_runner/test_runner.gyp index 36e166d..00d9033e6 100644 --- a/components/test_runner/test_runner.gyp +++ b/components/test_runner/test_runner.gyp
@@ -54,6 +54,8 @@ 'event_sender.h', 'gamepad_controller.cc', 'gamepad_controller.h', + 'gc_controller.cc', + 'gc_controller.h', 'mock_color_chooser.cc', 'mock_color_chooser.h', 'mock_constraints.cc',
diff --git a/components/web_view/frame.cc b/components/web_view/frame.cc index 29a22c1..9cc91631 100644 --- a/components/web_view/frame.cc +++ b/components/web_view/frame.cc
@@ -10,8 +10,8 @@ #include "base/bind.h" #include "base/callback.h" #include "base/stl_util.h" -#include "components/mus/public/cpp/view.h" -#include "components/mus/public/cpp/view_property.h" +#include "components/mus/public/cpp/window.h" +#include "components/mus/public/cpp/window_property.h" #include "components/web_view/frame_tree.h" #include "components/web_view/frame_tree_delegate.h" #include "components/web_view/frame_user_data.h" @@ -20,14 +20,14 @@ #include "mojo/common/url_type_converters.h" #include "url/gurl.h" -using mus::View; +using mus::Window; -DECLARE_VIEW_PROPERTY_TYPE(web_view::Frame*); +DECLARE_WINDOW_PROPERTY_TYPE(web_view::Frame*); namespace web_view { // Used to find the Frame associated with a View. -DEFINE_LOCAL_VIEW_PROPERTY_KEY(Frame*, kFrame, nullptr); +DEFINE_LOCAL_WINDOW_PROPERTY_KEY(Frame*, kFrame, nullptr); namespace { @@ -52,7 +52,7 @@ }; Frame::Frame(FrameTree* tree, - View* view, + Window* view, uint32_t frame_id, uint32_t app_id, ViewOwnership view_ownership, @@ -96,7 +96,8 @@ void Frame::Init(Frame* parent, mojo::ViewTreeClientPtr view_tree_client, - mojo::InterfaceRequest<mojom::Frame> frame_request) { + mojo::InterfaceRequest<mojom::Frame> frame_request, + base::TimeTicks navigation_start_time) { { // Set the FrameClient to null so that we don't notify the client of the // add before OnConnect(). @@ -110,7 +111,7 @@ ? ClientType::NEW_CHILD_FRAME : ClientType::EXISTING_FRAME_NEW_APP; InitClient(client_type, nullptr, view_tree_client.Pass(), - frame_request.Pass()); + frame_request.Pass(), navigation_start_time); tree_->delegate_->DidCreateFrame(this); @@ -119,7 +120,7 @@ } // static -Frame* Frame::FindFirstFrameAncestor(View* view) { +Frame* Frame::FindFirstFrameAncestor(Window* view) { while (view && !view->GetLocalProperty(kFrame)) view = view->parent(); return view ? view->GetLocalProperty(kFrame) : nullptr; @@ -190,7 +191,8 @@ void Frame::InitClient(ClientType client_type, scoped_ptr<FrameUserDataAndBinding> data_and_binding, mojo::ViewTreeClientPtr view_tree_client, - mojo::InterfaceRequest<mojom::Frame> frame_request) { + mojo::InterfaceRequest<mojom::Frame> frame_request, + base::TimeTicks navigation_start_time) { if (client_type == ClientType::EXISTING_FRAME_NEW_APP && view_tree_client.get()) { embedded_connection_id_ = kInvalidConnectionId; @@ -210,6 +212,7 @@ frame_client_->OnConnect( nullptr, tree_->change_id(), id_, mojom::VIEW_CONNECT_TYPE_USE_NEW, mojo::Array<mojom::FrameDataPtr>(), + navigation_start_time.ToInternalValue(), base::Bind(&OnConnectAck, base::Passed(&data_and_binding))); } else { std::vector<const Frame*> frames; @@ -229,7 +232,7 @@ client_type == ClientType::EXISTING_FRAME_SAME_APP ? mojom::VIEW_CONNECT_TYPE_USE_EXISTING : mojom::VIEW_CONNECT_TYPE_USE_NEW, - array.Pass(), + array.Pass(), navigation_start_time.ToInternalValue(), base::Bind(&OnConnectAck, base::Passed(&data_and_binding))); tree_->delegate_->DidStartNavigation(this); @@ -248,7 +251,8 @@ void Frame::ChangeClient(mojom::FrameClient* frame_client, scoped_ptr<FrameUserData> user_data, mojo::ViewTreeClientPtr view_tree_client, - uint32_t app_id) { + uint32_t app_id, + base::TimeTicks navigation_start_time) { while (!children_.empty()) delete children_[0]; @@ -273,7 +277,7 @@ app_id_ = app_id; InitClient(client_type, data_and_binding.Pass(), view_tree_client.Pass(), - nullptr); + nullptr, navigation_start_time); } void Frame::OnEmbedAck(bool success, mus::ConnectionSpecificId connection_id) { @@ -286,16 +290,18 @@ void Frame::OnWillNavigateAck(mojom::FrameClient* frame_client, scoped_ptr<FrameUserData> user_data, mojo::ViewTreeClientPtr view_tree_client, - uint32 app_id) { + uint32 app_id, + base::TimeTicks navigation_start_time) { DCHECK(waiting_for_on_will_navigate_ack_); DVLOG(2) << "Frame::OnWillNavigateAck id=" << id_; waiting_for_on_will_navigate_ack_ = false; - ChangeClient(frame_client, user_data.Pass(), view_tree_client.Pass(), app_id); + ChangeClient(frame_client, user_data.Pass(), view_tree_client.Pass(), app_id, + navigation_start_time); if (pending_navigate_.get()) StartNavigate(pending_navigate_.Pass()); } -void Frame::SetView(mus::View* view) { +void Frame::SetView(mus::Window* view) { DCHECK(!view_); DCHECK_EQ(id_, view->id()); view_ = view; @@ -353,13 +359,16 @@ DVLOG(2) << "Frame::StartNavigate id=" << id_ << " url=" << request->url; const GURL requested_url(request->url); + base::TimeTicks navigation_start_time = + base::TimeTicks::FromInternalValue(request->originating_time_ticks); tree_->delegate_->CanNavigateFrame( - this, request.Pass(), - base::Bind(&Frame::OnCanNavigateFrame, - navigate_weak_ptr_factory_.GetWeakPtr(), requested_url)); + this, request.Pass(), base::Bind(&Frame::OnCanNavigateFrame, + navigate_weak_ptr_factory_.GetWeakPtr(), + requested_url, navigation_start_time)); } void Frame::OnCanNavigateFrame(const GURL& url, + base::TimeTicks navigation_start_time, uint32_t app_id, mojom::FrameClient* frame_client, scoped_ptr<FrameUserData> user_data, @@ -372,14 +381,17 @@ // and ends up reusing it). DCHECK(!view_tree_client.get()); ChangeClient(frame_client, user_data.Pass(), view_tree_client.Pass(), - app_id); + app_id, navigation_start_time); } else { waiting_for_on_will_navigate_ack_ = true; DCHECK(view_tree_client.get()); // TODO(sky): url isn't correct here, it should be a security origin. - frame_client_->OnWillNavigate(url.spec(), base::Bind( - &Frame::OnWillNavigateAck, base::Unretained(this), frame_client, - base::Passed(&user_data), base::Passed(&view_tree_client), app_id)); + frame_client_->OnWillNavigate( + url.spec(), + base::Bind(&Frame::OnWillNavigateAck, base::Unretained(this), + frame_client, base::Passed(&user_data), + base::Passed(&view_tree_client), app_id, + navigation_start_time)); } } @@ -430,7 +442,7 @@ } } -void Frame::OnViewDestroying(mus::View* view) { +void Frame::OnWindowDestroying(mus::Window* view) { if (parent_) parent_->Remove(this); @@ -447,15 +459,16 @@ delete this; } -void Frame::OnViewEmbeddedAppDisconnected(mus::View* view) { - // See FrameTreeDelegate::OnViewEmbeddedAppDisconnected() for details of when +void Frame::OnWindowEmbeddedAppDisconnected(mus::Window* view) { + // See FrameTreeDelegate::OnWindowEmbeddedAppDisconnected() for details of + // when // this happens. // // Currently we have no way to distinguish between the cases that lead to this // being called, so we assume we can continue on. Continuing on is important // for html as it's entirely possible for a page to create a frame, navigate // to a bogus url and expect the frame to still exist. - tree_->delegate_->OnViewEmbeddedInFrameDisconnected(this); + tree_->delegate_->OnWindowEmbeddedInFrameDisconnected(this); } void Frame::PostMessageEventToFrame(uint32_t target_frame_id,
diff --git a/components/web_view/frame.h b/components/web_view/frame.h index 899781b1..38e10783 100644 --- a/components/web_view/frame.h +++ b/components/web_view/frame.h
@@ -10,8 +10,9 @@ #include "base/basictypes.h" #include "base/memory/scoped_ptr.h" +#include "base/time/time.h" #include "components/mus/public/cpp/types.h" -#include "components/mus/public/cpp/view_observer.h" +#include "components/mus/public/cpp/window_observer.h" #include "components/web_view/public/interfaces/frame.mojom.h" #include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h" @@ -51,13 +52,13 @@ // the argument |reuse_existing_view| supplied to OnConnect(). Typically the id // is that of content handler id, but this is left up to the FrameTreeDelegate // to decide. -class Frame : public mus::ViewObserver, public mojom::Frame { +class Frame : public mus::WindowObserver, public mojom::Frame { public: using ClientPropertyMap = std::map<std::string, std::vector<uint8_t>>; using FindCallback = mojo::Callback<void(bool)>; Frame(FrameTree* tree, - mus::View* view, + mus::Window* view, uint32_t frame_id, uint32_t app_id, ViewOwnership view_ownership, @@ -68,21 +69,22 @@ void Init(Frame* parent, mojo::ViewTreeClientPtr view_tree_client, - mojo::InterfaceRequest<mojom::Frame> frame_request); + mojo::InterfaceRequest<mojom::Frame> frame_request, + base::TimeTicks navigation_start_time); // Walks the View tree starting at |view| going up returning the first // Frame that is associated with |view|. For example, if |view| // has a Frame associated with it, then that is returned. Otherwise // this checks view->parent() and so on. - static Frame* FindFirstFrameAncestor(mus::View* view); + static Frame* FindFirstFrameAncestor(mus::Window* view); FrameTree* tree() { return tree_; } Frame* parent() { return parent_; } const Frame* parent() const { return parent_; } - mus::View* view() { return view_; } - const mus::View* view() const { return view_; } + mus::Window* view() { return view_; } + const mus::Window* view() const { return view_; } uint32_t id() const { return id_; } @@ -158,7 +160,8 @@ void InitClient(ClientType client_type, scoped_ptr<FrameUserDataAndBinding> data_and_binding, mojo::ViewTreeClientPtr view_tree_client, - mojo::InterfaceRequest<mojom::Frame> frame_request); + mojo::InterfaceRequest<mojom::Frame> frame_request, + base::TimeTicks navigation_start_time); // Callback from OnConnect(). This does nothing (other than destroying // |data_and_binding|). See InitClient() for details as to why destruction of @@ -173,16 +176,18 @@ void OnWillNavigateAck(mojom::FrameClient* frame_client, scoped_ptr<FrameUserData> user_data, mojo::ViewTreeClientPtr view_tree_client, - uint32 app_id); + uint32 app_id, + base::TimeTicks navigation_start_time); // Completes a navigation request; swapping the existing FrameClient to the // supplied arguments. void ChangeClient(mojom::FrameClient* frame_client, scoped_ptr<FrameUserData> user_data, mojo::ViewTreeClientPtr view_tree_client, - uint32 app_id); + uint32 app_id, + base::TimeTicks navigation_start_time); - void SetView(mus::View* view); + void SetView(mus::Window* view); // Adds this to |frames| and recurses through the children calling the // same function. @@ -196,6 +201,7 @@ // no View the navigation waits until the View is available. void StartNavigate(mojo::URLRequestPtr request); void OnCanNavigateFrame(const GURL& url, + base::TimeTicks navigation_start_time, uint32_t app_id, mojom::FrameClient* frame_client, scoped_ptr<FrameUserData> user_data, @@ -214,10 +220,10 @@ void NotifyFrameLoadingStateChanged(const Frame* frame, bool loading); void NotifyDispatchFrameLoadEvent(const Frame* frame); - // mus::ViewObserver: + // mus::WindowObserver: void OnTreeChanged(const TreeChangeParams& params) override; - void OnViewDestroying(mus::View* view) override; - void OnViewEmbeddedAppDisconnected(mus::View* view) override; + void OnWindowDestroying(mus::Window* view) override; + void OnWindowEmbeddedAppDisconnected(mus::Window* view) override; // mojom::Frame: void PostMessageEventToFrame(uint32_t target_frame_id, @@ -245,7 +251,7 @@ FrameTree* const tree_; // WARNING: this may be null. See class description for details. - mus::View* view_; + mus::Window* view_; // The connection id returned from ViewManager::Embed(). Frames created by // way of OnCreatedFrame() inherit the id from the parent. mus::ConnectionSpecificId embedded_connection_id_;
diff --git a/components/web_view/frame_apptest.cc b/components/web_view/frame_apptest.cc index 603b0b6..a8f0bb8c 100644 --- a/components/web_view/frame_apptest.cc +++ b/components/web_view/frame_apptest.cc
@@ -10,10 +10,11 @@ #include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/test/test_timeouts.h" -#include "components/mus/public/cpp/view_observer.h" -#include "components/mus/public/cpp/view_tree_connection.h" -#include "components/mus/public/cpp/view_tree_delegate.h" -#include "components/mus/public/cpp/view_tree_host_factory.h" +#include "base/time/time.h" +#include "components/mus/public/cpp/window_observer.h" +#include "components/mus/public/cpp/window_tree_connection.h" +#include "components/mus/public/cpp/window_tree_delegate.h" +#include "components/mus/public/cpp/window_tree_host_factory.h" #include "components/web_view/frame.h" #include "components/web_view/frame_connection.h" #include "components/web_view/frame_tree.h" @@ -26,8 +27,8 @@ #include "mojo/application/public/cpp/application_test_base.h" #include "mojo/application/public/cpp/service_provider_impl.h" -using mus::View; -using mus::ViewTreeConnection; +using mus::Window; +using mus::WindowTreeConnection; namespace web_view { @@ -124,12 +125,17 @@ return last_dispatch_load_event_frame_id_; } + base::TimeTicks last_navigation_start_time() const { + return last_navigation_start_time_; + } + // mojom::FrameClient: void OnConnect(mojom::FramePtr frame, uint32_t change_id, - uint32_t view_id, + uint32_t window_id, mojom::ViewConnectType view_connect_type, mojo::Array<mojom::FrameDataPtr> frames, + int64_t navigation_start_time_ticks, const OnConnectCallback& callback) override { connect_count_++; connect_frames_ = frames.Pass(); @@ -138,6 +144,9 @@ callback.Run(); if (!on_connect_callback_.is_null()) on_connect_callback_.Run(); + + last_navigation_start_time_ = + base::TimeTicks::FromInternalValue(navigation_start_time_ticks); } void OnFrameAdded(uint32_t change_id, mojom::FrameDataPtr frame) override { adds_.push_back(frame.Pass()); @@ -196,6 +205,7 @@ base::Closure on_dispatch_load_event_callback_; LoadingStateChangedNotification last_loading_state_changed_notification_; uint32_t last_dispatch_load_event_frame_id_; + base::TimeTicks last_navigation_start_time_; DISALLOW_COPY_AND_ASSIGN(TestFrameClient); }; @@ -206,7 +216,7 @@ // a single FrameClient. In other words this maintains the data structures // needed to represent a client side frame. To obtain one use // FrameTest::WaitForViewAndFrame(). -class ViewAndFrame : public mus::ViewTreeDelegate { +class ViewAndFrame : public mus::WindowTreeDelegate { public: ~ViewAndFrame() override { if (view_) @@ -214,7 +224,7 @@ } // The View associated with the frame. - mus::View* view() { return view_; } + mus::Window* view() { return view_; } TestFrameClient* test_frame_client() { return &test_frame_tree_client_; } mojom::Frame* server_frame() { return test_frame_tree_client_.server_frame(); @@ -226,7 +236,7 @@ ViewAndFrame() : view_(nullptr), frame_client_binding_(&test_frame_tree_client_) {} - void set_view(View* view) { view_ = view; } + void set_view(Window* view) { view_ = view; } // Runs a message loop until the view and frame data have been received. void WaitForViewAndFrame() { run_loop_.Run(); } @@ -255,16 +265,16 @@ run_loop_.Quit(); } - // Overridden from ViewTreeDelegate: - void OnEmbed(View* root) override { + // Overridden from WindowTreeDelegate: + void OnEmbed(Window* root) override { view_ = root; QuitRunLoopIfNecessary(); } - void OnConnectionLost(ViewTreeConnection* connection) override { + void OnConnectionLost(WindowTreeConnection* connection) override { view_ = nullptr; } - mus::View* view_; + mus::Window* view_; base::RunLoop run_loop_; TestFrameClient test_frame_tree_client_; mojo::Binding<mojom::FrameClient> frame_client_binding_; @@ -274,36 +284,44 @@ class FrameTest : public mojo::test::ApplicationTestBase, public mojo::ApplicationDelegate, - public mus::ViewTreeDelegate, + public mus::WindowTreeDelegate, public mojo::InterfaceFactory<mojo::ViewTreeClient>, public mojo::InterfaceFactory<mojom::FrameClient> { public: FrameTest() : most_recent_connection_(nullptr), window_manager_(nullptr) {} - ViewTreeConnection* most_recent_connection() { + WindowTreeConnection* most_recent_connection() { return most_recent_connection_; } protected: - ViewTreeConnection* window_manager() { return window_manager_; } + WindowTreeConnection* window_manager() { return window_manager_; } TestFrameTreeDelegate* frame_tree_delegate() { return frame_tree_delegate_.get(); } FrameTree* frame_tree() { return frame_tree_.get(); } ViewAndFrame* root_view_and_frame() { return root_view_and_frame_.get(); } - scoped_ptr<ViewAndFrame> NavigateFrame(ViewAndFrame* view_and_frame) { + scoped_ptr<ViewAndFrame> NavigateFrameWithStartTime( + ViewAndFrame* view_and_frame, + base::TimeTicks navigation_start_time) { mojo::URLRequestPtr request(mojo::URLRequest::New()); request->url = mojo::String::From(application_impl()->url()); + request->originating_time_ticks = navigation_start_time.ToInternalValue(); view_and_frame->server_frame()->RequestNavigate( mojom::NAVIGATION_TARGET_TYPE_EXISTING_FRAME, view_and_frame->view()->id(), request.Pass()); return WaitForViewAndFrame(); } + scoped_ptr<ViewAndFrame> NavigateFrame(ViewAndFrame* view_and_frame) { + return NavigateFrameWithStartTime(view_and_frame, base::TimeTicks()); + } + // Creates a new shared frame as a child of |parent|. scoped_ptr<ViewAndFrame> CreateChildViewAndFrame(ViewAndFrame* parent) { - mus::View* child_frame_view = parent->view()->connection()->CreateView(); + mus::Window* child_frame_view = + parent->view()->connection()->CreateWindow(); parent->view()->AddChild(child_frame_view); scoped_ptr<ViewAndFrame> view_and_frame(new ViewAndFrame); @@ -340,18 +358,18 @@ return true; } - // Overridden from ViewTreeDelegate: - void OnEmbed(View* root) override { + // Overridden from WindowTreeDelegate: + void OnEmbed(Window* root) override { most_recent_connection_ = root->connection(); QuitRunLoop(); } - void OnConnectionLost(ViewTreeConnection* connection) override {} + void OnConnectionLost(WindowTreeConnection* connection) override {} // Overridden from testing::Test: void SetUp() override { ApplicationTestBase::SetUp(); - mus::CreateSingleViewTreeHost(application_impl(), this, &host_); + mus::CreateSingleWindowTreeHost(application_impl(), this, &host_); ASSERT_TRUE(DoRunLoopWithTimeout()); std::swap(window_manager_, most_recent_connection_); @@ -364,12 +382,12 @@ mojom::FrameClient* frame_client = frame_connection->frame_client(); mojo::ViewTreeClientPtr view_tree_client = frame_connection->GetViewTreeClient(); - mus::View* frame_root_view = window_manager()->CreateView(); + mus::Window* frame_root_view = window_manager()->CreateWindow(); window_manager()->GetRoot()->AddChild(frame_root_view); - frame_tree_.reset( - new FrameTree(0u, frame_root_view, view_tree_client.Pass(), - frame_tree_delegate_.get(), frame_client, - frame_connection.Pass(), Frame::ClientPropertyMap())); + frame_tree_.reset(new FrameTree( + 0u, frame_root_view, view_tree_client.Pass(), + frame_tree_delegate_.get(), frame_client, frame_connection.Pass(), + Frame::ClientPropertyMap(), base::TimeTicks::Now())); root_view_and_frame_ = WaitForViewAndFrame(); } @@ -386,13 +404,13 @@ mojo::ApplicationConnection* connection, mojo::InterfaceRequest<mojo::ViewTreeClient> request) override { if (view_and_frame_) { - mus::ViewTreeConnection::Create( + mus::WindowTreeConnection::Create( view_and_frame_.get(), request.Pass(), - mus::ViewTreeConnection::CreateType::DONT_WAIT_FOR_EMBED); + mus::WindowTreeConnection::CreateType::DONT_WAIT_FOR_EMBED); } else { - mus::ViewTreeConnection::Create( + mus::WindowTreeConnection::Create( this, request.Pass(), - mus::ViewTreeConnection::CreateType::DONT_WAIT_FOR_EMBED); + mus::WindowTreeConnection::CreateType::DONT_WAIT_FOR_EMBED); } } @@ -410,10 +428,10 @@ mojo::ViewTreeHostPtr host_; // Used to receive the most recent view manager loaded by an embed action. - ViewTreeConnection* most_recent_connection_; + WindowTreeConnection* most_recent_connection_; // The View Manager connection held by the window manager (app running at the // root view). - ViewTreeConnection* window_manager_; + WindowTreeConnection* window_manager_; scoped_ptr<ViewAndFrame> view_and_frame_; @@ -461,7 +479,7 @@ scoped_ptr<ViewAndFrame> navigated_child_view_and_frame = NavigateFrame(child_view_and_frame.get()).Pass(); - // Delete the ViewTreeConnection for the child, which should trigger + // Delete the WindowTreeConnection for the child, which should trigger // notification. delete navigated_child_view_and_frame->view()->connection(); ASSERT_EQ(1u, frame_tree()->root()->children().size()); @@ -535,4 +553,20 @@ ->last_dispatch_load_event_frame_id(); EXPECT_EQ(child_frame_id, frame_id); } + +TEST_F(FrameTest, PassAlongNavigationStartTime) { + scoped_ptr<ViewAndFrame> child_view_and_frame( + CreateChildViewAndFrame(root_view_and_frame())); + ASSERT_TRUE(child_view_and_frame); + + base::TimeTicks navigation_start_time = base::TimeTicks::FromInternalValue(1); + scoped_ptr<ViewAndFrame> navigated_child_view_and_frame = + NavigateFrameWithStartTime(child_view_and_frame.get(), + navigation_start_time) + .Pass(); + EXPECT_EQ(navigation_start_time, + navigated_child_view_and_frame->test_frame_client() + ->last_navigation_start_time()); +} + } // namespace web_view
diff --git a/components/web_view/frame_tree.cc b/components/web_view/frame_tree.cc index e8d071f..7132739 100644 --- a/components/web_view/frame_tree.cc +++ b/components/web_view/frame_tree.cc
@@ -10,12 +10,13 @@ namespace web_view { FrameTree::FrameTree(uint32_t root_app_id, - mus::View* view, + mus::Window* view, mojo::ViewTreeClientPtr view_tree_client, FrameTreeDelegate* delegate, mojom::FrameClient* root_client, scoped_ptr<FrameUserData> user_data, - const Frame::ClientPropertyMap& client_properties) + const Frame::ClientPropertyMap& client_properties, + base::TimeTicks navigation_start_time) : view_(view), delegate_(delegate), root_(new Frame(this, @@ -28,7 +29,7 @@ client_properties)), progress_(0.f), change_id_(1u) { - root_->Init(nullptr, view_tree_client.Pass(), nullptr); + root_->Init(nullptr, view_tree_client.Pass(), nullptr, navigation_start_time); } FrameTree::~FrameTree() { @@ -48,13 +49,13 @@ mojom::FrameClient* raw_client = client.get(); scoped_ptr<FrameUserData> user_data = delegate_->CreateUserDataForNewFrame(client.Pass()); - mus::View* frame_view = root_->view()->GetChildById(frame_id); + mus::Window* frame_view = root_->view()->GetChildById(frame_id); // |frame_view| may be null if the View hasn't been created yet. If this is // the case the View will be connected to the Frame in Frame::OnTreeChanged. Frame* frame = new Frame(this, frame_view, frame_id, app_id, ViewOwnership::OWNS_VIEW, raw_client, user_data.Pass(), client_properties); - frame->Init(parent, nullptr, frame_request.Pass()); + frame->Init(parent, nullptr, frame_request.Pass(), base::TimeTicks()); return frame; }
diff --git a/components/web_view/frame_tree.h b/components/web_view/frame_tree.h index aadcdba..f252ceb 100644 --- a/components/web_view/frame_tree.h +++ b/components/web_view/frame_tree.h
@@ -5,6 +5,7 @@ #ifndef COMPONENTS_WEB_VIEW_FRAME_TREE_H_ #define COMPONENTS_WEB_VIEW_FRAME_TREE_H_ +#include "base/time/time.h" #include "components/mus/public/interfaces/view_tree.mojom.h" #include "components/web_view/frame.h" #include "third_party/mojo/src/mojo/public/cpp/bindings/array.h" @@ -36,12 +37,13 @@ // |root_app_id| is a unique identifier of the app providing |root_client|. // See Frame for details on app id's. FrameTree(uint32_t root_app_id, - mus::View* view, + mus::Window* view, mojo::ViewTreeClientPtr view_tree_client, FrameTreeDelegate* delegate, mojom::FrameClient* root_client, scoped_ptr<FrameUserData> user_data, - const Frame::ClientPropertyMap& client_properties); + const Frame::ClientPropertyMap& client_properties, + base::TimeTicks navigation_start_time); ~FrameTree(); const Frame* root() const { return root_; } @@ -72,7 +74,7 @@ const mojo::String& name, const mojo::Array<uint8_t>& value); - mus::View* view_; + mus::Window* view_; FrameTreeDelegate* delegate_;
diff --git a/components/web_view/frame_tree_delegate.cc b/components/web_view/frame_tree_delegate.cc index c04ec70..dbc3773 100644 --- a/components/web_view/frame_tree_delegate.cc +++ b/components/web_view/frame_tree_delegate.cc
@@ -8,7 +8,7 @@ void FrameTreeDelegate::DidCreateFrame(Frame* frame) {} void FrameTreeDelegate::DidDestroyFrame(Frame* frame) {} -void FrameTreeDelegate::OnViewEmbeddedInFrameDisconnected(Frame* frame) {} +void FrameTreeDelegate::OnWindowEmbeddedInFrameDisconnected(Frame* frame) {} void FrameTreeDelegate::OnFindInFrameCountUpdated(int32_t request_id, Frame* frame, int32_t count,
diff --git a/components/web_view/frame_tree_delegate.h b/components/web_view/frame_tree_delegate.h index 4b317a79..55be5612 100644 --- a/components/web_view/frame_tree_delegate.h +++ b/components/web_view/frame_tree_delegate.h
@@ -86,7 +86,7 @@ // . The app is still alive, but is shutting down. // Frame does nothing in response to this, but the delegate may wish to take // action. - virtual void OnViewEmbeddedInFrameDisconnected(Frame* frame); + virtual void OnWindowEmbeddedInFrameDisconnected(Frame* frame); // Reports the current find state back to our owner. virtual void OnFindInFrameCountUpdated(int32_t request_id,
diff --git a/components/web_view/navigation_controller.cc b/components/web_view/navigation_controller.cc index ef6010b..87304fa 100644 --- a/components/web_view/navigation_controller.cc +++ b/components/web_view/navigation_controller.cc
@@ -75,7 +75,7 @@ pending_entry_index_ = current_index - 1; // TODO(erg): Transition type handled here. - NavigateToPendingEntry(ReloadType::NO_RELOAD); + NavigateToPendingEntry(ReloadType::NO_RELOAD, true); } void NavigationController::GoForward() { @@ -93,17 +93,19 @@ pending_entry_index_ = current_index + 1; // TODO(erg): Transition type handled here. - NavigateToPendingEntry(ReloadType::NO_RELOAD); + NavigateToPendingEntry(ReloadType::NO_RELOAD, true); } void NavigationController::LoadURL(mojo::URLRequestPtr request) { // TODO(erg): This mimics part of NavigationControllerImpl::LoadURL(), minus // all the error checking. SetPendingEntry(make_scoped_ptr(new NavigationEntry(request.Pass()))); - NavigateToPendingEntry(ReloadType::NO_RELOAD); + NavigateToPendingEntry(ReloadType::NO_RELOAD, false); } -void NavigationController::NavigateToPendingEntry(ReloadType reload_type) { +void NavigationController::NavigateToPendingEntry( + ReloadType reload_type, + bool update_navigation_start_time) { // TODO(erg): Deal with session history navigations while trying to navigate // to a slow-to-commit page. @@ -117,7 +119,8 @@ // TODO(erg): Eventually, we need to deal with restoring the state of the // full tree. For now, we'll just shell back to the WebView. - delegate_->OnNavigate(pending_entry_->BuildURLRequest()); + delegate_->OnNavigate( + pending_entry_->BuildURLRequest(update_navigation_start_time)); } void NavigationController::DiscardPendingEntry(bool was_failure) {
diff --git a/components/web_view/navigation_controller.h b/components/web_view/navigation_controller.h index 1d4a0ae..635dfe5 100644 --- a/components/web_view/navigation_controller.h +++ b/components/web_view/navigation_controller.h
@@ -41,7 +41,8 @@ void LoadURL(mojo::URLRequestPtr request); - void NavigateToPendingEntry(ReloadType reload_type); + void NavigateToPendingEntry(ReloadType reload_type, + bool update_navigation_start_time); // Takes ownership of a pending entry, and adds it to the current list. //
diff --git a/components/web_view/navigation_entry.cc b/components/web_view/navigation_entry.cc index 0b3aaa8..24d6db92 100644 --- a/components/web_view/navigation_entry.cc +++ b/components/web_view/navigation_entry.cc
@@ -7,14 +7,20 @@ namespace web_view { NavigationEntry::NavigationEntry(mojo::URLRequestPtr original_request) - : url_request_(original_request.Pass()) {} + : url_request_(original_request.Pass()) { + if (url_request_.originating_time().is_null()) + url_request_.set_originating_time(base::TimeTicks::Now()); +} NavigationEntry::NavigationEntry(const GURL& raw_url) : url_request_(raw_url) {} NavigationEntry::~NavigationEntry() {} -mojo::URLRequestPtr NavigationEntry::BuildURLRequest() const { +mojo::URLRequestPtr NavigationEntry::BuildURLRequest( + bool update_originating_time) { + if (update_originating_time) + url_request_.set_originating_time(base::TimeTicks::Now()); return url_request_.Clone(); }
diff --git a/components/web_view/navigation_entry.h b/components/web_view/navigation_entry.h index db3df6a..2e5f6a1 100644 --- a/components/web_view/navigation_entry.h +++ b/components/web_view/navigation_entry.h
@@ -21,7 +21,7 @@ // Builds a copy of the URLRequest that generated this navigation. This // method is heavyweight as it clones a few mojo pipes. - mojo::URLRequestPtr BuildURLRequest() const; + mojo::URLRequestPtr BuildURLRequest(bool update_originating_time); private: // TODO(erg): This is not enough information to regenerate the state of the
diff --git a/components/web_view/pending_web_view_load.cc b/components/web_view/pending_web_view_load.cc index 54fa39b54..fcb40db 100644 --- a/components/web_view/pending_web_view_load.cc +++ b/components/web_view/pending_web_view_load.cc
@@ -19,6 +19,8 @@ void PendingWebViewLoad::Init(mojo::URLRequestPtr request) { DCHECK(!frame_connection_); pending_url_ = GURL(request->url); + navigation_start_time_ = + base::TimeTicks::FromInternalValue(request->originating_time_ticks); frame_connection_.reset(new FrameConnection); frame_connection_->Init(web_view_->app_, request.Pass(), base::Bind(&PendingWebViewLoad::OnGotContentHandlerID,
diff --git a/components/web_view/pending_web_view_load.h b/components/web_view/pending_web_view_load.h index b2a11217..b7070bd 100644 --- a/components/web_view/pending_web_view_load.h +++ b/components/web_view/pending_web_view_load.h
@@ -8,6 +8,7 @@ #include <string> #include "base/memory/scoped_ptr.h" +#include "base/time/time.h" #include "mojo/services/network/public/interfaces/url_loader.mojom.h" #include "url/gurl.h" @@ -35,6 +36,10 @@ const GURL& pending_url() const { return pending_url_; } + base::TimeTicks navigation_start_time() const { + return navigation_start_time_; + } + private: void OnGotContentHandlerID(); @@ -45,6 +50,8 @@ scoped_ptr<FrameConnection> frame_connection_; + base::TimeTicks navigation_start_time_; + DISALLOW_COPY_AND_ASSIGN(PendingWebViewLoad); };
diff --git a/components/web_view/public/cpp/web_view.cc b/components/web_view/public/cpp/web_view.cc index d2ae310..51fd1d6 100644 --- a/components/web_view/public/cpp/web_view.cc +++ b/components/web_view/public/cpp/web_view.cc
@@ -5,7 +5,7 @@ #include "components/web_view/public/cpp/web_view.h" #include "base/bind.h" -#include "components/mus/public/cpp/view.h" +#include "components/mus/public/cpp/window.h" #include "mojo/application/public/cpp/application_impl.h" namespace web_view { @@ -20,7 +20,7 @@ WebView::WebView(mojom::WebViewClient* client) : binding_(client) {} WebView::~WebView() {} -void WebView::Init(mojo::ApplicationImpl* app, mus::View* view) { +void WebView::Init(mojo::ApplicationImpl* app, mus::Window* window) { mojo::URLRequestPtr request(mojo::URLRequest::New()); request->url = "mojo:web_view"; @@ -35,8 +35,8 @@ mojo::ViewTreeClientPtr view_tree_client; web_view_->GetViewTreeClient(GetProxy(&view_tree_client)); - view->Embed(view_tree_client.Pass(), mojo::ViewTree::ACCESS_POLICY_EMBED_ROOT, - base::Bind(&OnEmbed)); + window->Embed(view_tree_client.Pass(), + mojo::ViewTree::ACCESS_POLICY_EMBED_ROOT, base::Bind(&OnEmbed)); } } // namespace web_view
diff --git a/components/web_view/public/cpp/web_view.h b/components/web_view/public/cpp/web_view.h index b10c0d3..0eae5ede 100644 --- a/components/web_view/public/cpp/web_view.h +++ b/components/web_view/public/cpp/web_view.h
@@ -15,7 +15,7 @@ } namespace mus { -class View; +class Window; } namespace web_view { @@ -25,7 +25,7 @@ explicit WebView(mojom::WebViewClient* client); ~WebView(); - void Init(mojo::ApplicationImpl* app, mus::View* view); + void Init(mojo::ApplicationImpl* app, mus::Window* window); mojom::WebView* web_view() { return web_view_.get(); }
diff --git a/components/web_view/public/interfaces/frame.mojom b/components/web_view/public/interfaces/frame.mojom index 2808cfde..4290882 100644 --- a/components/web_view/public/interfaces/frame.mojom +++ b/components/web_view/public/interfaces/frame.mojom
@@ -143,12 +143,15 @@ // Called once per client. |frame_data| gives the contents of the tree. // |view_id| is the id of the view the FrameClient should render to. If a // ViewTreeClient is asked for then |view_id| is the same id as that of the - // View supplied to ViewTreeClient::OnEmbed(). + // View supplied to ViewTreeClient::OnEmbed(). |navigation_start_time_ticks| + // is the time when the navigation resulting in this OnConnect() call was + // started. OnConnect(Frame? frame, uint32 change_id, uint32 view_id, ViewConnectType view_connect_type, - array<FrameData>? frame_data) => (); + array<FrameData>? frame_data, + int64 navigation_start_time_ticks) => (); // Called when a new frame is added to the tree. OnFrameAdded(uint32 change_id, FrameData frame_data);
diff --git a/components/web_view/test_frame_tree_delegate.cc b/components/web_view/test_frame_tree_delegate.cc index 2b7ee8cc..8c439b2 100644 --- a/components/web_view/test_frame_tree_delegate.cc +++ b/components/web_view/test_frame_tree_delegate.cc
@@ -98,7 +98,7 @@ } } -void TestFrameTreeDelegate::OnViewEmbeddedInFrameDisconnected(Frame* frame) { +void TestFrameTreeDelegate::OnWindowEmbeddedInFrameDisconnected(Frame* frame) { if (waiting_for_frame_disconnected_ == frame) { waiting_for_frame_disconnected_ = nullptr; run_loop_->Quit();
diff --git a/components/web_view/test_frame_tree_delegate.h b/components/web_view/test_frame_tree_delegate.h index 1f021ee..21cb581 100644 --- a/components/web_view/test_frame_tree_delegate.h +++ b/components/web_view/test_frame_tree_delegate.h
@@ -33,7 +33,7 @@ // Waits for DidDestroyFrame() to be called with |frame|. void WaitForDestroyFrame(Frame* frame); - // Waits for OnViewEmbeddedInFrameDisconnected() to be called with |frame|. + // Waits for OnWindowEmbeddedInFrameDisconnected() to be called with |frame|. void WaitForFrameDisconnected(Frame* frame); // TestFrameTreeDelegate: @@ -53,7 +53,7 @@ void DidNavigateLocally(Frame* source, const GURL& url) override; void DidCreateFrame(Frame* frame) override; void DidDestroyFrame(Frame* frame) override; - void OnViewEmbeddedInFrameDisconnected(Frame* frame) override; + void OnWindowEmbeddedInFrameDisconnected(Frame* frame) override; private: bool is_waiting() const { return run_loop_.get(); }
diff --git a/components/web_view/test_runner/test_runner_application_delegate.cc b/components/web_view/test_runner/test_runner_application_delegate.cc index 24d2c517..76e5bc4d 100644 --- a/components/web_view/test_runner/test_runner_application_delegate.cc +++ b/components/web_view/test_runner/test_runner_application_delegate.cc
@@ -15,10 +15,10 @@ #include "base/path_service.h" #include "base/thread_task_runner_handle.h" #include "base/threading/thread_restrictions.h" -#include "components/mus/public/cpp/scoped_view_ptr.h" -#include "components/mus/public/cpp/view.h" -#include "components/mus/public/cpp/view_tree_connection.h" -#include "components/mus/public/cpp/view_tree_host_factory.h" +#include "components/mus/public/cpp/scoped_window_ptr.h" +#include "components/mus/public/cpp/window.h" +#include "components/mus/public/cpp/window_tree_connection.h" +#include "components/mus/public/cpp/window_tree_host_factory.h" #include "components/test_runner/blink_test_platform_support.h" #include "mojo/application/public/cpp/application_connection.h" #include "mojo/application/public/cpp/application_impl.h" @@ -40,7 +40,7 @@ TestRunnerApplicationDelegate::~TestRunnerApplicationDelegate() { if (root_) - mus::ScopedViewPtr::DeleteViewOrViewManager(root_); + mus::ScopedWindowPtr::DeleteWindowOrWindowManager(root_); } void TestRunnerApplicationDelegate::LaunchURL(const GURL& test_url) { @@ -55,7 +55,7 @@ void TestRunnerApplicationDelegate::Terminate() { if (root_) - mus::ScopedViewPtr::DeleteViewOrViewManager(root_); + mus::ScopedWindowPtr::DeleteWindowOrWindowManager(root_); } //////////////////////////////////////////////////////////////////////////////// @@ -66,7 +66,7 @@ NOTREACHED() << "Test environment could not be properly set up for blink."; } app_ = app; - mus::CreateSingleViewTreeHost(app_, this, &host_); + mus::CreateSingleWindowTreeHost(app_, this, &host_); } bool TestRunnerApplicationDelegate::ConfigureIncomingConnection( @@ -78,7 +78,7 @@ //////////////////////////////////////////////////////////////////////////////// // mus::ViewTreeDelegate implementation: -void TestRunnerApplicationDelegate::OnEmbed(mus::View* root) { +void TestRunnerApplicationDelegate::OnEmbed(mus::Window* root) { root_ = root; // If this is a sys-check, then terminate in the next cycle. @@ -94,7 +94,7 @@ const gfx::Size kViewportSize(800, 600); host_->SetSize(mojo::Size::From(kViewportSize)); - content_ = root_->connection()->CreateView(); + content_ = root_->connection()->CreateWindow(); root_->AddChild(content_); content_->SetBounds(*mojo::Rect::From(gfx::Rect(kViewportSize))); content_->SetVisible(true); @@ -111,7 +111,7 @@ } void TestRunnerApplicationDelegate::OnConnectionLost( - mus::ViewTreeConnection* connection) { + mus::WindowTreeConnection* connection) { root_ = nullptr; app_->Quit(); }
diff --git a/components/web_view/test_runner/test_runner_application_delegate.h b/components/web_view/test_runner/test_runner_application_delegate.h index 03d5b5e..6299580 100644 --- a/components/web_view/test_runner/test_runner_application_delegate.h +++ b/components/web_view/test_runner/test_runner_application_delegate.h
@@ -7,7 +7,7 @@ #include "base/command_line.h" #include "base/memory/scoped_ptr.h" -#include "components/mus/public/cpp/view_tree_delegate.h" +#include "components/mus/public/cpp/window_tree_delegate.h" #include "components/mus/public/interfaces/view_tree_host.mojom.h" #include "components/test_runner/test_info_extractor.h" #include "components/web_view/public/cpp/web_view.h" @@ -27,7 +27,7 @@ class TestRunnerApplicationDelegate : public mojo::ApplicationDelegate, - public mus::ViewTreeDelegate, + public mus::WindowTreeDelegate, public mojom::WebViewClient, public LayoutTestRunner, public mojo::InterfaceFactory<LayoutTestRunner> { @@ -44,9 +44,9 @@ bool ConfigureIncomingConnection( mojo::ApplicationConnection* connection) override; - // mus::ViewTreeDelegate: - void OnEmbed(mus::View* root) override; - void OnConnectionLost(mus::ViewTreeConnection* connection) override; + // mus::WindowTreeDelegate: + void OnEmbed(mus::Window* root) override; + void OnConnectionLost(mus::WindowTreeConnection* connection) override; // mojom::WebViewClient: void TopLevelNavigateRequest(mojo::URLRequestPtr request) override; @@ -71,8 +71,8 @@ mojo::ApplicationImpl* app_; mojo::ViewTreeHostPtr host_; - mus::View* root_; - mus::View* content_; + mus::Window* root_; + mus::Window* content_; scoped_ptr<WebView> web_view_; scoped_ptr<test_runner::TestInfoExtractor> test_extractor_;
diff --git a/components/web_view/url_request_cloneable.cc b/components/web_view/url_request_cloneable.cc index 4ee870aa..db601a5 100644 --- a/components/web_view/url_request_cloneable.cc +++ b/components/web_view/url_request_cloneable.cc
@@ -24,7 +24,9 @@ auto_follow_redirects_(original_request->auto_follow_redirects), bypass_cache_(original_request->bypass_cache), original_body_null_(original_request->body.is_null()), - body_(original_request->body.size()) { + body_(original_request->body.size()), + originating_time_(base::TimeTicks::FromInternalValue( + original_request->originating_time_ticks)) { // TODO(erg): Maybe we can do some sort of async copy here? for (size_t i = 0; i < original_request->body.size(); ++i) { mojo::common::BlockingCopyToString(original_request->body[i].Pass(), @@ -71,6 +73,8 @@ } } + request->originating_time_ticks = originating_time_.ToInternalValue(); + return request.Pass(); }
diff --git a/components/web_view/url_request_cloneable.h b/components/web_view/url_request_cloneable.h index b8b3c3d0..18f3b3e9 100644 --- a/components/web_view/url_request_cloneable.h +++ b/components/web_view/url_request_cloneable.h
@@ -9,6 +9,7 @@ #include <vector> #include "base/basictypes.h" +#include "base/time/time.h" #include "mojo/services/network/public/interfaces/url_loader.mojom.h" #include "url/gurl.h" @@ -28,6 +29,11 @@ // Creates a new URLRequest. mojo::URLRequestPtr Clone() const; + base::TimeTicks originating_time() const { return originating_time_; } + void set_originating_time(base::TimeTicks value) { + originating_time_ = value; + } + private: // All of these are straight from mojo::URLRequest. mojo::String url_; @@ -47,6 +53,8 @@ // AsURLRequest() is called. std::vector<std::string> body_; + base::TimeTicks originating_time_; + DISALLOW_COPY_AND_ASSIGN(URLRequestCloneable); };
diff --git a/components/web_view/web_view_apptest.cc b/components/web_view/web_view_apptest.cc index 05faf55..63e42da 100644 --- a/components/web_view/web_view_apptest.cc +++ b/components/web_view/web_view_apptest.cc
@@ -10,10 +10,10 @@ #include "base/logging.h" #include "base/path_service.h" #include "base/run_loop.h" -#include "components/mus/public/cpp/scoped_view_ptr.h" -#include "components/mus/public/cpp/tests/view_manager_test_base.h" -#include "components/mus/public/cpp/view.h" -#include "components/mus/public/cpp/view_tree_connection.h" +#include "components/mus/public/cpp/scoped_window_ptr.h" +#include "components/mus/public/cpp/tests/window_server_test_base.h" +#include "components/mus/public/cpp/window.h" +#include "components/mus/public/cpp/window_tree_connection.h" #include "mojo/util/filename_util.h" #include "url/gurl.h" @@ -40,7 +40,7 @@ } } -class WebViewTest : public mus::ViewManagerTestBase, +class WebViewTest : public mus::WindowServerTestBase, public mojom::WebViewClient { public: WebViewTest() @@ -94,25 +94,26 @@ // Overridden from ApplicationDelegate: void Initialize(mojo::ApplicationImpl* app) override { - ViewManagerTestBase::Initialize(app); + WindowServerTestBase::Initialize(app); app_ = app; } // Overridden from ViewTreeDelegate: - void OnEmbed(mus::View* root) override { - content_ = root->connection()->CreateView(); + void OnEmbed(mus::Window* root) override { + content_ = root->connection()->CreateWindow(); content_->SetBounds(root->bounds()); root->AddChild(content_); content_->SetVisible(true); web_view_.Init(app_, content_); - ViewManagerTestBase::OnEmbed(root); + WindowServerTestBase::OnEmbed(root); } void TearDown() override { - mus::ScopedViewPtr::DeleteViewOrViewManager(window_manager()->GetRoot()); - ViewManagerTestBase::TearDown(); + mus::ScopedWindowPtr::DeleteWindowOrWindowManager( + window_manager()->GetRoot()); + WindowServerTestBase::TearDown(); } // Overridden from web_view::mojom::WebViewClient: @@ -148,7 +149,7 @@ mojo::ApplicationImpl* app_; - mus::View* content_; + mus::Window* content_; web_view::WebView web_view_;
diff --git a/components/web_view/web_view_impl.cc b/components/web_view/web_view_impl.cc index 3320733..b590e0f 100644 --- a/components/web_view/web_view_impl.cc +++ b/components/web_view/web_view_impl.cc
@@ -9,9 +9,9 @@ #include "base/bind.h" #include "base/command_line.h" #include "components/devtools_service/public/cpp/switches.h" -#include "components/mus/public/cpp/scoped_view_ptr.h" -#include "components/mus/public/cpp/view.h" -#include "components/mus/public/cpp/view_tree_connection.h" +#include "components/mus/public/cpp/scoped_window_ptr.h" +#include "components/mus/public/cpp/window.h" +#include "components/mus/public/cpp/window_tree_connection.h" #include "components/web_view/client_initiated_frame_connection.h" #include "components/web_view/frame.h" #include "components/web_view/frame_connection.h" @@ -59,7 +59,7 @@ content_->RemoveObserver(this); if (root_) { root_->RemoveObserver(this); - mus::ScopedViewPtr::DeleteViewOrViewManager(root_); + mus::ScopedWindowPtr::DeleteWindowOrWindowManager(root_); } } @@ -74,7 +74,7 @@ client_->TopLevelNavigationStarted(pending_url.spec()); - content_ = root_->connection()->CreateView(); + content_ = root_->connection()->CreateWindow(); content_->SetBounds(*mojo::Rect::From( gfx::Rect(0, 0, root_->bounds().width, root_->bounds().height))); root_->AddChild(content_); @@ -99,7 +99,8 @@ const uint32_t content_handler_id = frame_connection->GetContentHandlerID(); frame_tree_.reset(new FrameTree(content_handler_id, content_, view_tree_client.Pass(), this, frame_client, - frame_connection.Pass(), client_properties)); + frame_connection.Pass(), client_properties, + pending_load->navigation_start_time())); } void WebViewImpl::PreOrderDepthFirstTraverseTree(Frame* node, @@ -118,9 +119,9 @@ void WebViewImpl::GetViewTreeClient( mojo::InterfaceRequest<mojo::ViewTreeClient> view_tree_client) { - mus::ViewTreeConnection::Create( + mus::WindowTreeConnection::Create( this, view_tree_client.Pass(), - mus::ViewTreeConnection::CreateType::DONT_WAIT_FOR_EMBED); + mus::WindowTreeConnection::CreateType::DONT_WAIT_FOR_EMBED); } void WebViewImpl::Find(const mojo::String& search_text, @@ -145,9 +146,9 @@ } //////////////////////////////////////////////////////////////////////////////// -// WebViewImpl, mus::ViewTreeDelegate implementation: +// WebViewImpl, mus::WindowTreeDelegate implementation: -void WebViewImpl::OnEmbed(mus::View* root) { +void WebViewImpl::OnEmbed(mus::Window* root) { // We must have been granted embed root priviledges, otherwise we can't // Embed() in any descendants. DCHECK(root->connection()->IsEmbedRoot()); @@ -158,16 +159,16 @@ OnLoad(pending_load_->pending_url()); } -void WebViewImpl::OnConnectionLost(mus::ViewTreeConnection* connection) { +void WebViewImpl::OnConnectionLost(mus::WindowTreeConnection* connection) { root_ = nullptr; } //////////////////////////////////////////////////////////////////////////////// // WebViewImpl, mus::ViewObserver implementation: -void WebViewImpl::OnViewBoundsChanged(mus::View* view, - const mojo::Rect& old_bounds, - const mojo::Rect& new_bounds) { +void WebViewImpl::OnWindowBoundsChanged(mus::Window* view, + const mojo::Rect& old_bounds, + const mojo::Rect& new_bounds) { if (view != content_) { mojo::Rect rect; rect.width = new_bounds.width; @@ -177,7 +178,7 @@ } } -void WebViewImpl::OnViewDestroyed(mus::View* view) { +void WebViewImpl::OnWindowDestroyed(mus::Window* view) { // |FrameTree| cannot outlive the content view. if (view == content_) { frame_tree_.reset();
diff --git a/components/web_view/web_view_impl.h b/components/web_view/web_view_impl.h index 534c5aa2..1e2125e 100644 --- a/components/web_view/web_view_impl.h +++ b/components/web_view/web_view_impl.h
@@ -10,8 +10,8 @@ #include "base/macros.h" #include "base/memory/scoped_ptr.h" -#include "components/mus/public/cpp/view_observer.h" -#include "components/mus/public/cpp/view_tree_delegate.h" +#include "components/mus/public/cpp/window_observer.h" +#include "components/mus/public/cpp/window_tree_delegate.h" #include "components/web_view/find_controller.h" #include "components/web_view/find_controller_delegate.h" #include "components/web_view/frame_devtools_agent_delegate.h" @@ -39,8 +39,8 @@ } class WebViewImpl : public mojom::WebView, - public mus::ViewTreeDelegate, - public mus::ViewObserver, + public mus::WindowTreeDelegate, + public mus::WindowObserver, public FrameTreeDelegate, public FrameDevToolsAgentDelegate, public NavigationControllerDelegate, @@ -70,15 +70,15 @@ void GoBack() override; void GoForward() override; - // Overridden from mus::ViewTreeDelegate: - void OnEmbed(mus::View* root) override; - void OnConnectionLost(mus::ViewTreeConnection* connection) override; + // Overridden from mus::WindowTreeDelegate: + void OnEmbed(mus::Window* root) override; + void OnConnectionLost(mus::WindowTreeConnection* connection) override; - // Overridden from mus::ViewObserver: - void OnViewBoundsChanged(mus::View* view, - const mojo::Rect& old_bounds, - const mojo::Rect& new_bounds) override; - void OnViewDestroyed(mus::View* view) override; + // Overridden from mus::WindowObserver: + void OnWindowBoundsChanged(mus::Window* view, + const mojo::Rect& old_bounds, + const mojo::Rect& new_bounds) override; + void OnWindowDestroyed(mus::Window* view) override; // Overridden from FrameTreeDelegate: scoped_ptr<FrameUserData> CreateUserDataForNewFrame( @@ -118,8 +118,8 @@ mojo::ApplicationImpl* app_; mojom::WebViewClientPtr client_; mojo::StrongBinding<WebView> binding_; - mus::View* root_; - mus::View* content_; + mus::Window* root_; + mus::Window* content_; scoped_ptr<FrameTree> frame_tree_; // When LoadRequest() is called a PendingWebViewLoad is created to wait for
diff --git a/content/browser/accessibility/browser_accessibility_win.cc b/content/browser/accessibility/browser_accessibility_win.cc index c0a64e0..a932c4d 100644 --- a/content/browser/accessibility/browser_accessibility_win.cc +++ b/content/browser/accessibility/browser_accessibility_win.cc
@@ -269,7 +269,7 @@ gfx::Point point(x_left, y_top); if (!GetGlobalBoundsRect().Contains(point)) { - // Return S_FALSE and VT_EMPTY when the outside the object's boundaries. + // Return S_FALSE and VT_EMPTY when outside the object's boundaries. child->vt = VT_EMPTY; return S_FALSE; } @@ -2463,33 +2463,109 @@ } // -// IAccessibleHyperlink not implemented. +// IAccessibleHyperlink methods. // +// Currently, only text links are supported. STDMETHODIMP BrowserAccessibilityWin::get_anchor(long index, VARIANT* anchor) { - return E_NOTIMPL; + if (!instance_active() || !IsHyperlink()) + return E_FAIL; + + // IA2 text links can have only one anchor, that is the text inside them. + if (index != 0 || !anchor) + return E_INVALIDARG; + + BSTR hypertext = SysAllocString(TextForIAccessibleText().c_str()); + DCHECK(hypertext); + anchor->vt = VT_BSTR; + anchor->bstrVal = hypertext; + + // Returning S_FALSE is not mentioned in the IA2 Spec, but it might have been + // an oversight. + if (!SysStringLen(hypertext)) + return S_FALSE; + + return S_OK; } -STDMETHODIMP -BrowserAccessibilityWin::get_anchorTarget(long index, VARIANT* anchor_target) { - return E_NOTIMPL; + +// Currently, only text links are supported. +STDMETHODIMP BrowserAccessibilityWin::get_anchorTarget(long index, + VARIANT* anchor_target) { + if (!instance_active() || !IsHyperlink()) + return E_FAIL; + + // IA2 text links can have at most one target, that is when they represent an + // HTML hyperlink, i.e. an <a> element with a "href" attribute. + if (index != 0 || !anchor_target) + return E_INVALIDARG; + + BSTR target; + if (!(ia_state() & STATE_SYSTEM_LINKED) || + FAILED(GetStringAttributeAsBstr(ui::AX_ATTR_URL, &target))) { + target = SysAllocString(L""); + } + DCHECK(target); + anchor_target->vt = VT_BSTR; + anchor_target->bstrVal = target; + + // Returning S_FALSE is not mentioned in the IA2 Spec, but it might have been + // an oversight. + if (!SysStringLen(target)) + return S_FALSE; + + return S_OK; } + STDMETHODIMP BrowserAccessibilityWin::get_startIndex(long* index) { - return E_NOTIMPL; + if (!instance_active() || !IsHyperlink()) + return E_FAIL; + + if (!index) + return E_INVALIDARG; + + int32 hypertext_offset = 0; + const auto parent = GetParent(); + if (parent) { + hypertext_offset = + parent->ToBrowserAccessibilityWin()->GetHypertextOffsetFromChild(*this); + } + *index = static_cast<LONG>(hypertext_offset); + return S_OK; } + STDMETHODIMP BrowserAccessibilityWin::get_endIndex(long* index) { - return E_NOTIMPL; + LONG start_index; + HRESULT hr = get_startIndex(&start_index); + if (hr == S_OK) + *index = start_index + 1; + return hr; } + +// This method is deprecated in the IA2 Spec. STDMETHODIMP BrowserAccessibilityWin::get_valid(boolean* valid) { return E_NOTIMPL; } // -// IAccessibleAction not implemented. +// IAccessibleAction mostly not implemented. // STDMETHODIMP BrowserAccessibilityWin::nActions(long* n_actions) { - return E_NOTIMPL; + if (!instance_active()) + return E_FAIL; + + if (!n_actions) + return E_INVALIDARG; + + // Required for IAccessibleHyperlink::anchor/anchorTarget to work properly. + // TODO(nektar): Implement the rest of the logic required by this interface. + if (IsHyperlink()) + *n_actions = 1; + else + *n_actions = 0; + return S_OK; } + STDMETHODIMP BrowserAccessibilityWin::doAction(long action_index) { return E_NOTIMPL; } @@ -2996,7 +3072,7 @@ // IServiceProvider methods. // -STDMETHODIMP BrowserAccessibilityWin::QueryService(REFGUID guidService, +STDMETHODIMP BrowserAccessibilityWin::QueryService(REFGUID guid_service, REFIID riid, void** object) { if (!instance_active()) @@ -3008,7 +3084,7 @@ if (riid == IID_IAccessible2) BrowserAccessibilityStateImpl::GetInstance()->EnableAccessibility(); - if (guidService == GUID_IAccessibleContentDocument) { + if (guid_service == GUID_IAccessibleContentDocument) { // Special Mozilla extension: return the accessible for the root document. // Screen readers use this to distinguish between a document loaded event // on the root document vs on an iframe. @@ -3016,22 +3092,22 @@ IID_IAccessible2, object); } - if (guidService == IID_IAccessible || - guidService == IID_IAccessible2 || - guidService == IID_IAccessibleAction || - guidService == IID_IAccessibleApplication || - guidService == IID_IAccessibleHyperlink || - guidService == IID_IAccessibleHypertext || - guidService == IID_IAccessibleImage || - guidService == IID_IAccessibleTable || - guidService == IID_IAccessibleTable2 || - guidService == IID_IAccessibleTableCell || - guidService == IID_IAccessibleText || - guidService == IID_IAccessibleValue || - guidService == IID_ISimpleDOMDocument || - guidService == IID_ISimpleDOMNode || - guidService == IID_ISimpleDOMText || - guidService == GUID_ISimpleDOM) { + if (guid_service == IID_IAccessible || + guid_service == IID_IAccessible2 || + guid_service == IID_IAccessibleAction || + guid_service == IID_IAccessibleApplication || + guid_service == IID_IAccessibleHyperlink || + guid_service == IID_IAccessibleHypertext || + guid_service == IID_IAccessibleImage || + guid_service == IID_IAccessibleTable || + guid_service == IID_IAccessibleTable2 || + guid_service == IID_IAccessibleTableCell || + guid_service == IID_IAccessibleText || + guid_service == IID_IAccessibleValue || + guid_service == IID_ISimpleDOMDocument || + guid_service == IID_ISimpleDOMNode || + guid_service == IID_ISimpleDOMText || + guid_service == GUID_ISimpleDOM) { return QueryInterface(riid, object); } @@ -3155,6 +3231,12 @@ *object = NULL; return E_NOINTERFACE; } + } else if (iid == IID_IAccessibleHyperlink) { + auto ax_object = reinterpret_cast<const BrowserAccessibilityWin*>(this_ptr); + if (!ax_object || !ax_object->IsHyperlink()) { + *object = nullptr; + return E_NOINTERFACE; + } } return CComObjectRootBase::InternalQueryInterface( @@ -3653,6 +3735,19 @@ } } +bool BrowserAccessibilityWin::IsHyperlink() const { + int32 hyperlink_index = -1; + const auto parent = GetParent(); + if (parent) { + hyperlink_index = + parent->ToBrowserAccessibilityWin()->GetHyperlinkIndexFromChild(*this); + } + + if (hyperlink_index >= 0) + return true; + return false; +} + int32 BrowserAccessibilityWin::GetHyperlinkIndexFromChild( const BrowserAccessibilityWin& child) const { if (hyperlinks().empty())
diff --git a/content/browser/accessibility/browser_accessibility_win.h b/content/browser/accessibility/browser_accessibility_win.h index 8d2971b..094fea7 100644 --- a/content/browser/accessibility/browser_accessibility_win.h +++ b/content/browser/accessibility/browser_accessibility_win.h
@@ -523,15 +523,16 @@ CONTENT_EXPORT STDMETHODIMP get_hyperlinkIndex(long char_index, long* hyperlink_index) override; - // IAccessibleHyperlink not implemented. + // IAccessibleHyperlink methods. CONTENT_EXPORT STDMETHODIMP get_anchor(long index, VARIANT* anchor) override; - CONTENT_EXPORT STDMETHODIMP - get_anchorTarget(long index, VARIANT* anchor_target) override; + CONTENT_EXPORT STDMETHODIMP get_anchorTarget(long index, + VARIANT* anchor_target) override; CONTENT_EXPORT STDMETHODIMP get_startIndex(long* index) override; CONTENT_EXPORT STDMETHODIMP get_endIndex(long* index) override; + // This method is deprecated in the IA2 Spec and so we don't implement it. CONTENT_EXPORT STDMETHODIMP get_valid(boolean* valid) override; - // IAccessibleAction not implemented. + // IAccessibleAction mostly not implemented. CONTENT_EXPORT STDMETHODIMP nActions(long* n_actions) override; CONTENT_EXPORT STDMETHODIMP doAction(long action_index) override; CONTENT_EXPORT STDMETHODIMP @@ -775,11 +776,18 @@ void IntAttributeToIA2(ui::AXIntAttribute attribute, const char* ia2_attr); - // Functions that help when retrieving hyperlinks and hypertext offsets. - // Return -1 in case of failure. + // + // Helper methods for IA2 hyperlinks. + // // Hyperlink is an IA2 misnomer. It refers to objects embedded within other // objects, such as a numbered list within a contenteditable div. - // Also, text that includes embedded objects is called hypertext. + // Also, in IA2, text that includes embedded objects is called hypertext. + + // Returns true if the current object is an IA2 hyperlink. + bool IsHyperlink() const; + + // Functions for retrieving offsets for hyperlinks and hypertext. + // Return -1 in case of failure. int32 GetHyperlinkIndexFromChild(const BrowserAccessibilityWin& child) const; int32 GetHypertextOffsetFromHyperlinkIndex(int32 hyperlink_index) const; int32 GetHypertextOffsetFromChild(const BrowserAccessibilityWin& child) const; @@ -792,11 +800,14 @@ // offset. Otherwise, returns either 0 or the length of the hypertext // depending on the direction of the selection. // Returns -1 in case of unexpected failure, e.g. the selection endpoint - // cannot be located in the accessibility tree. + // cannot be found in the accessibility tree. int GetHypertextOffsetFromEndpoint( const BrowserAccessibilityWin& endpoint_object, int endpoint_offset) const; + // + // Selection helper functions. + // // The following functions retrieve the endpoints of the current selection. // First they check for a local selection found on the current control, e.g. // when querying the selection on a textarea. @@ -805,7 +816,7 @@ int GetSelectionFocus() const; // Retrieves the selection offsets in the way required by the IA2 APIs. // selection_start and selection_end are -1 when there is no selection active - // inside this object. + // on this object. // The greatest of the two offsets is one past the last character of the // selection.) void GetSelectionOffsets(int* selection_start, int* selection_end) const;
diff --git a/content/browser/accessibility/browser_accessibility_win_unittest.cc b/content/browser/accessibility/browser_accessibility_win_unittest.cc index 7b4fbcd..b7a41e77 100644 --- a/content/browser/accessibility/browser_accessibility_win_unittest.cc +++ b/content/browser/accessibility/browser_accessibility_win_unittest.cc
@@ -1205,6 +1205,160 @@ ASSERT_EQ(0, CountedBrowserAccessibility::num_instances()); } +TEST_F(BrowserAccessibilityTest, TestIAccessibleHyperlink) { + ui::AXNodeData root; + root.id = 1; + root.role = ui::AX_ROLE_ROOT_WEB_AREA; + root.state = (1 << ui::AX_STATE_READ_ONLY) | (1 << ui::AX_STATE_FOCUSABLE); + + ui::AXNodeData div; + div.id = 2; + div.role = ui::AX_ROLE_DIV; + div.state = (1 << ui::AX_STATE_FOCUSABLE); + + ui::AXNodeData text; + text.id = 3; + text.role = ui::AX_ROLE_STATIC_TEXT; + text.SetName("Click "); + + ui::AXNodeData link; + link.id = 4; + link.role = ui::AX_ROLE_LINK; + link.state = (1 << ui::AX_STATE_FOCUSABLE) | (1 << ui::AX_STATE_LINKED); + link.SetName("here"); + link.AddStringAttribute(ui::AX_ATTR_URL, "example.com"); + + root.child_ids.push_back(2); + div.child_ids.push_back(3); + div.child_ids.push_back(4); + + CountedBrowserAccessibility::reset(); + scoped_ptr<BrowserAccessibilityManager> manager( + BrowserAccessibilityManager::Create( + MakeAXTreeUpdate(root, div, link, text), nullptr, + new CountedBrowserAccessibilityFactory())); + ASSERT_EQ(4, CountedBrowserAccessibility::num_instances()); + + ASSERT_NE(nullptr, manager->GetRoot()); + BrowserAccessibilityWin* root_accessible = + manager->GetRoot()->ToBrowserAccessibilityWin(); + ASSERT_NE(nullptr, root_accessible); + ASSERT_EQ(1U, root_accessible->PlatformChildCount()); + + BrowserAccessibilityWin* div_accessible = + root_accessible->PlatformGetChild(0)->ToBrowserAccessibilityWin(); + ASSERT_NE(nullptr, div_accessible); + ASSERT_EQ(2U, div_accessible->PlatformChildCount()); + + BrowserAccessibilityWin* text_accessible = + div_accessible->PlatformGetChild(0)->ToBrowserAccessibilityWin(); + ASSERT_NE(nullptr, text_accessible); + BrowserAccessibilityWin* link_accessible = + div_accessible->PlatformGetChild(1)->ToBrowserAccessibilityWin(); + ASSERT_NE(nullptr, link_accessible); + + // -1 is never a valid value. + LONG n_actions = -1; + LONG start_index = -1; + LONG end_index = -1; + + base::win::ScopedComPtr<IAccessibleHyperlink> hyperlink; + base::win::ScopedVariant anchor; + base::win::ScopedVariant anchor_target; + base::win::ScopedBstr bstr; + + base::string16 div_hypertext(L"Click "); + div_hypertext.push_back(BrowserAccessibilityWin::kEmbeddedCharacter); + + // div_accessible and link_accessible are the only IA2 hyperlinks. + EXPECT_HRESULT_FAILED(root_accessible->QueryInterface( + IID_IAccessibleHyperlink, reinterpret_cast<void**>(hyperlink.Receive()))); + hyperlink.Release(); + EXPECT_HRESULT_SUCCEEDED(div_accessible->QueryInterface( + IID_IAccessibleHyperlink, reinterpret_cast<void**>(hyperlink.Receive()))); + hyperlink.Release(); + EXPECT_HRESULT_FAILED(text_accessible->QueryInterface( + IID_IAccessibleHyperlink, reinterpret_cast<void**>(hyperlink.Receive()))); + hyperlink.Release(); + EXPECT_HRESULT_SUCCEEDED(link_accessible->QueryInterface( + IID_IAccessibleHyperlink, reinterpret_cast<void**>(hyperlink.Receive()))); + hyperlink.Release(); + + EXPECT_HRESULT_SUCCEEDED(root_accessible->nActions(&n_actions)); + EXPECT_EQ(0, n_actions); + EXPECT_HRESULT_SUCCEEDED(div_accessible->nActions(&n_actions)); + EXPECT_EQ(1, n_actions); + EXPECT_HRESULT_SUCCEEDED(text_accessible->nActions(&n_actions)); + EXPECT_EQ(0, n_actions); + EXPECT_HRESULT_SUCCEEDED(link_accessible->nActions(&n_actions)); + EXPECT_EQ(1, n_actions); + + EXPECT_HRESULT_FAILED(root_accessible->get_anchor(0, anchor.Receive())); + anchor.Reset(); + HRESULT hr = div_accessible->get_anchor(0, anchor.Receive()); + EXPECT_EQ(S_OK, hr); + EXPECT_EQ(VT_BSTR, anchor.type()); + bstr.Reset(V_BSTR(anchor.ptr())); + EXPECT_STREQ(div_hypertext.c_str(), bstr); + bstr.Reset(); + anchor.Reset(); + EXPECT_HRESULT_FAILED(text_accessible->get_anchor(0, anchor.Receive())); + anchor.Reset(); + hr = link_accessible->get_anchor(0, anchor.Receive()); + EXPECT_EQ(S_OK, hr); + EXPECT_EQ(VT_BSTR, anchor.type()); + bstr.Reset(V_BSTR(anchor.ptr())); + EXPECT_STREQ(L"here", bstr); + bstr.Reset(); + anchor.Reset(); + EXPECT_HRESULT_FAILED(div_accessible->get_anchor(1, anchor.Receive())); + anchor.Reset(); + EXPECT_HRESULT_FAILED(link_accessible->get_anchor(1, anchor.Receive())); + anchor.Reset(); + + EXPECT_HRESULT_FAILED( + root_accessible->get_anchorTarget(0, anchor_target.Receive())); + anchor_target.Reset(); + hr = div_accessible->get_anchorTarget(0, anchor_target.Receive()); + EXPECT_EQ(S_FALSE, hr); + EXPECT_EQ(VT_BSTR, anchor_target.type()); + bstr.Reset(V_BSTR(anchor_target.ptr())); + // Target should be empty. + EXPECT_STREQ(L"", bstr); + bstr.Reset(); + anchor_target.Reset(); + EXPECT_HRESULT_FAILED( + text_accessible->get_anchorTarget(0, anchor_target.Receive())); + anchor_target.Reset(); + hr = link_accessible->get_anchorTarget(0, anchor_target.Receive()); + EXPECT_EQ(S_OK, hr); + EXPECT_EQ(VT_BSTR, anchor_target.type()); + bstr.Reset(V_BSTR(anchor_target.ptr())); + EXPECT_STREQ(L"example.com", bstr); + bstr.Reset(); + anchor_target.Reset(); + EXPECT_HRESULT_FAILED( + div_accessible->get_anchorTarget(1, anchor_target.Receive())); + anchor_target.Reset(); + EXPECT_HRESULT_FAILED( + link_accessible->get_anchorTarget(1, anchor_target.Receive())); + anchor_target.Reset(); + + EXPECT_HRESULT_FAILED(root_accessible->get_startIndex(&start_index)); + EXPECT_HRESULT_SUCCEEDED(div_accessible->get_startIndex(&start_index)); + EXPECT_EQ(0, start_index); + EXPECT_HRESULT_FAILED(text_accessible->get_startIndex(&start_index)); + EXPECT_HRESULT_SUCCEEDED(link_accessible->get_startIndex(&start_index)); + EXPECT_EQ(6, start_index); + + EXPECT_HRESULT_FAILED(root_accessible->get_endIndex(&end_index)); + EXPECT_HRESULT_SUCCEEDED(div_accessible->get_endIndex(&end_index)); + EXPECT_EQ(1, end_index); + EXPECT_HRESULT_FAILED(text_accessible->get_endIndex(&end_index)); + EXPECT_HRESULT_SUCCEEDED(link_accessible->get_endIndex(&end_index)); + EXPECT_EQ(7, end_index); +} + TEST_F(BrowserAccessibilityTest, TestPlatformDeepestFirstLastChild) { ui::AXNodeData root; root.id = 1;
diff --git a/content/browser/compositor/delegated_frame_host.cc b/content/browser/compositor/delegated_frame_host.cc index abc001e..ca8a0d87 100644 --- a/content/browser/compositor/delegated_frame_host.cc +++ b/content/browser/compositor/delegated_frame_host.cc
@@ -254,7 +254,7 @@ resize_lock_->UnlockCompositor(); } -void DelegatedFrameHost::DidReceiveFrameFromRenderer( +void DelegatedFrameHost::AttemptFrameSubscriberCapture( const gfx::Rect& damage_rect) { if (!frame_subscriber() || !CanCopyToVideoFrame()) return; @@ -298,14 +298,25 @@ // screenshots) since those copy requests do not specify |frame_subscriber()| // as a source. request->set_source(frame_subscriber()); - request->set_area(gfx::Rect(current_frame_size_in_dip_)); if (subscriber_texture.get()) { request->SetTextureMailbox( cc::TextureMailbox(subscriber_texture->mailbox(), subscriber_texture->target(), subscriber_texture->sync_point())); } - RequestCopyOfOutput(request.Pass()); + + if (surface_factory_.get()) { + // To avoid unnecessary composites, go directly to the Surface rather than + // through RequestCopyOfOutput (which goes through the browser + // compositor). + if (!request_copy_of_output_callback_for_testing_.is_null()) + request_copy_of_output_callback_for_testing_.Run(request.Pass()); + else + surface_factory_->RequestCopyOfSurface(surface_id_, request.Pass()); + } else { + request->set_area(gfx::Rect(current_frame_size_in_dip_)); + RequestCopyOfOutput(request.Pass()); + } } void DelegatedFrameHost::SwapDelegatedFrame( @@ -475,7 +486,10 @@ } else { AddOnCommitCallbackAndDisableLocks(base::Closure()); } - DidReceiveFrameFromRenderer(damage_rect); + // With Surfaces, the notification that the surface will be drawn notifies + // the frame subscriber. + if (!use_surfaces_) + AttemptFrameSubscriberCapture(damage_rect); if (frame_provider_.get() || !surface_id_.is_null()) delegated_frame_evictor_->SwappedFrame( client_->DelegatedFrameHostIsVisible()); @@ -536,6 +550,13 @@ SendReturnedDelegatedResources(last_output_surface_id_); } +void DelegatedFrameHost::WillDrawSurface(cc::SurfaceId id, + const gfx::Rect& damage_rect) { + if (id != surface_id_) + return; + AttemptFrameSubscriberCapture(damage_rect); +} + void DelegatedFrameHost::EvictDelegatedFrame() { client_->DelegatedFrameHostGetLayer()->SetShowSolidColorContent(); frame_provider_ = NULL;
diff --git a/content/browser/compositor/delegated_frame_host.h b/content/browser/compositor/delegated_frame_host.h index aa3ce5b1..c9662cbc 100644 --- a/content/browser/compositor/delegated_frame_host.h +++ b/content/browser/compositor/delegated_frame_host.h
@@ -116,6 +116,7 @@ // cc::SurfaceFactoryClient implementation. void ReturnResources(const cc::ReturnedResourceArray& resources) override; + void WillDrawSurface(cc::SurfaceId id, const gfx::Rect& damage_rect) override; bool CanCopyToBitmap() const; @@ -246,7 +247,7 @@ // Called to consult the current |frame_subscriber_|, to determine and maybe // initiate a copy-into-video-frame request. - void DidReceiveFrameFromRenderer(const gfx::Rect& damage_rect); + void AttemptFrameSubscriberCapture(const gfx::Rect& damage_rect); DelegatedFrameHostClient* const client_; ui::Compositor* compositor_;
diff --git a/content/browser/frame_host/cross_process_frame_connector.cc b/content/browser/frame_host/cross_process_frame_connector.cc index 7fb24a4..be3b397 100644 --- a/content/browser/frame_host/cross_process_frame_connector.cc +++ b/content/browser/frame_host/cross_process_frame_connector.cc
@@ -7,6 +7,7 @@ #include "cc/surfaces/surface.h" #include "cc/surfaces/surface_manager.h" #include "content/browser/compositor/surface_utils.h" +#include "content/browser/frame_host/frame_tree.h" #include "content/browser/frame_host/frame_tree_node.h" #include "content/browser/frame_host/render_frame_host_manager.h" #include "content/browser/frame_host/render_frame_proxy_host.h" @@ -163,6 +164,12 @@ static_cast<RenderWidgetHostViewBase*>(rwhv)->GetScreenInfo(results); } +void CrossProcessFrameConnector::UpdateCursor(const WebCursor& cursor) { + RenderWidgetHostViewBase* root_view = GetRootRenderWidgetHostView(); + if (root_view) + root_view->UpdateCursor(cursor); +} + void CrossProcessFrameConnector::OnForwardInputEvent( const blink::WebInputEvent* event) { if (!view_) @@ -218,4 +225,14 @@ view_->SetSize(frame_rect.size()); } +RenderWidgetHostViewBase* +CrossProcessFrameConnector::GetRootRenderWidgetHostView() { + return static_cast<RenderWidgetHostViewBase*>( + frame_proxy_in_parent_renderer_->frame_tree_node() + ->frame_tree() + ->root() + ->current_frame_host() + ->GetView()); +} + } // namespace content
diff --git a/content/browser/frame_host/cross_process_frame_connector.h b/content/browser/frame_host/cross_process_frame_connector.h index 48547213..abe3a04 100644 --- a/content/browser/frame_host/cross_process_frame_connector.h +++ b/content/browser/frame_host/cross_process_frame_connector.h
@@ -29,7 +29,9 @@ namespace content { class RenderFrameProxyHost; class RenderWidgetHostImpl; +class RenderWidgetHostViewBase; class RenderWidgetHostViewChildFrame; +class WebCursor; // CrossProcessFrameConnector provides the platform view abstraction for // RenderWidgetHostViewChildFrame allowing RWHVChildFrame to remain ignorant @@ -96,6 +98,7 @@ gfx::Rect ChildFrameRect(); float device_scale_factor() const { return device_scale_factor_; } void GetScreenInfo(blink::WebScreenInfo* results); + void UpdateCursor(const WebCursor& cursor); private: // Handlers for messages received from the parent frame. @@ -113,6 +116,9 @@ void SetDeviceScaleFactor(float scale_factor); void SetSize(gfx::Rect frame_rect); + // Retrieve the view for the top-level frame under the same WebContents. + RenderWidgetHostViewBase* GetRootRenderWidgetHostView(); + // The RenderFrameProxyHost that routes messages to the parent frame's // renderer process. RenderFrameProxyHost* frame_proxy_in_parent_renderer_;
diff --git a/content/browser/frame_host/render_frame_host_manager_browsertest.cc b/content/browser/frame_host/render_frame_host_manager_browsertest.cc index 0cea2ed1..10370990 100644 --- a/content/browser/frame_host/render_frame_host_manager_browsertest.cc +++ b/content/browser/frame_host/render_frame_host_manager_browsertest.cc
@@ -20,6 +20,7 @@ #include "content/browser/web_contents/web_contents_impl.h" #include "content/browser/webui/web_ui_impl.h" #include "content/common/content_constants_internal.h" +#include "content/common/input_messages.h" #include "content/common/site_isolation_policy.h" #include "content/public/browser/navigation_controller.h" #include "content/public/browser/navigation_entry.h" @@ -2115,4 +2116,51 @@ ResourceDispatcherHost::Get()->SetDelegate(nullptr); } +// Tests that InputMsg type IPCs are ignored by swapped out RenderViews. It +// uses the SetFocus IPC, as RenderView has a CHECK to ensure that condition +// never happens. +IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest, + InputMsgToSwappedOutRVHIsIgnored) { + StartEmbeddedServer(); + EXPECT_TRUE(NavigateToURL( + shell(), embedded_test_server()->GetURL("a.com", "/title1.html"))); + + // Open a popup to navigate cross-process. + Shell* new_shell = + OpenPopup(shell()->web_contents(), GURL(url::kAboutBlankURL), "foo"); + EXPECT_EQ(shell()->web_contents()->GetSiteInstance(), + new_shell->web_contents()->GetSiteInstance()); + + // Keep a pointer to the RenderViewHost, which will be in swapped out + // state after navigating cross-process. This is how this test is causing + // a swapped out RenderView to receive InputMsg IPC message. + WebContentsImpl* new_web_contents = + static_cast<WebContentsImpl*>(new_shell->web_contents()); + FrameTreeNode* new_root = new_web_contents->GetFrameTree()->root(); + RenderViewHostImpl* rvh = new_web_contents->GetRenderViewHost(); + + // Navigate the popup to a different site, so the |rvh| is swapped out. + EXPECT_TRUE(NavigateToURL( + new_shell, embedded_test_server()->GetURL("b.com", "/title2.html"))); + EXPECT_NE(shell()->web_contents()->GetSiteInstance(), + new_shell->web_contents()->GetSiteInstance()); + EXPECT_EQ(rvh, new_root->render_manager()->GetSwappedOutRenderViewHost( + shell()->web_contents()->GetSiteInstance())); + + // Setup a process observer to ensure there is no crash and send the IPC + // message. + RenderProcessHostWatcher watcher( + rvh->GetProcess(), RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); + rvh->Send(new InputMsg_SetFocus(rvh->GetRoutingID(), true)); + + // The test must wait for a process to exit, but if the IPC message is + // properly ignored, there will be no crash. Therefore, navigate the + // original window to the same site as the popup, which will just exit the + // process cleanly. + EXPECT_TRUE(NavigateToURL( + shell(), embedded_test_server()->GetURL("b.com", "/title3.html"))); + watcher.Wait(); + EXPECT_TRUE(watcher.did_exit_normally()); +} + } // namespace content
diff --git a/content/browser/frame_host/render_widget_host_view_child_frame.cc b/content/browser/frame_host/render_widget_host_view_child_frame.cc index 07cd5b53..88bf587 100644 --- a/content/browser/frame_host/render_widget_host_view_child_frame.cc +++ b/content/browser/frame_host/render_widget_host_view_child_frame.cc
@@ -162,6 +162,8 @@ } void RenderWidgetHostViewChildFrame::UpdateCursor(const WebCursor& cursor) { + if (frame_connector_) + frame_connector_->UpdateCursor(cursor); } void RenderWidgetHostViewChildFrame::SetIsLoading(bool is_loading) {
diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc index 4920cf2e9..96c864e2 100644 --- a/content/browser/renderer_host/compositor_impl_android.cc +++ b/content/browser/renderer_host/compositor_impl_android.cc
@@ -387,7 +387,10 @@ } } -void CompositorImpl::SetWindowSurface(ANativeWindow* window) { +void CompositorImpl::SetSurface(jobject surface) { + JNIEnv* env = base::android::AttachCurrentThread(); + base::android::ScopedJavaLocalRef<jobject> j_surface(env, surface); + GpuSurfaceTracker* tracker = GpuSurfaceTracker::Get(); if (window_) { @@ -396,9 +399,19 @@ tracker->RemoveSurface(surface_id_); ANativeWindow_release(window_); window_ = NULL; + UnregisterViewSurface(surface_id_); surface_id_ = 0; } + ANativeWindow* window = NULL; + if (surface) { + // Note: This ensures that any local references used by + // ANativeWindow_fromSurface are released immediately. This is needed as a + // workaround for https://code.google.com/p/android/issues/detail?id=68174 + base::android::ScopedJavaLocalFrame scoped_local_reference_frame(env); + window = ANativeWindow_fromSurface(env, surface); + } + if (window) { window_ = window; ANativeWindow_acquire(window); @@ -406,34 +419,10 @@ tracker->SetSurfaceHandle( surface_id_, gfx::GLSurfaceHandle(surface_id_, gfx::NATIVE_DIRECT)); - SetVisible(true); - } -} - -void CompositorImpl::SetSurface(jobject surface) { - JNIEnv* env = base::android::AttachCurrentThread(); - base::android::ScopedJavaLocalRef<jobject> j_surface(env, surface); - - // First, shut down the GL context. - int surface_id = surface_id_; - SetWindowSurface(NULL); - // Then, cleanup any existing surface references. - if (surface_id) - UnregisterViewSurface(surface_id); - - // Now, set the new surface if we have one. - ANativeWindow* window = NULL; - if (surface) { - // Note: This ensures that any local references used by - // ANativeWindow_fromSurface are released immediately. This is needed as a - // workaround for https://code.google.com/p/android/issues/detail?id=68174 - base::android::ScopedJavaLocalFrame scoped_local_reference_frame(env); - window = ANativeWindow_fromSurface(env, surface); - } - if (window) { - SetWindowSurface(window); - ANativeWindow_release(window); + // Register first, SetVisible() might create an OutputSurface. RegisterViewSurface(surface_id_, j_surface.obj()); + SetVisible(true); + ANativeWindow_release(window); } }
diff --git a/content/browser/renderer_host/compositor_impl_android.h b/content/browser/renderer_host/compositor_impl_android.h index fd454db..223ae081 100644 --- a/content/browser/renderer_host/compositor_impl_android.h +++ b/content/browser/renderer_host/compositor_impl_android.h
@@ -119,7 +119,6 @@ base::TimeDelta vsync_period) override; void SetNeedsAnimate() override; - void SetWindowSurface(ANativeWindow* window); void SetVisible(bool visible); enum CompositingTrigger {
diff --git a/content/browser/renderer_host/input/input_router.h b/content/browser/renderer_host/input/input_router.h index 027f9fe..186022f 100644 --- a/content/browser/renderer_host/input/input_router.h +++ b/content/browser/renderer_host/input/input_router.h
@@ -35,8 +35,7 @@ virtual void SendWheelEvent( const MouseWheelEventWithLatencyInfo& wheel_event) = 0; virtual void SendKeyboardEvent( - const NativeWebKeyboardEventWithLatencyInfo& key_event, - bool is_shortcut) = 0; + const NativeWebKeyboardEventWithLatencyInfo& key_event) = 0; virtual void SendGestureEvent( const GestureEventWithLatencyInfo& gesture_event) = 0; virtual void SendTouchEvent(
diff --git a/content/browser/renderer_host/input/input_router_impl.cc b/content/browser/renderer_host/input/input_router_impl.cc index ebc0040a..7aabd609 100644 --- a/content/browser/renderer_host/input/input_router_impl.cc +++ b/content/browser/renderer_host/input/input_router_impl.cc
@@ -152,12 +152,11 @@ LOCAL_HISTOGRAM_COUNTS_100("Renderer.WheelQueueSize", coalesced_mouse_wheel_events_.size()); - FilterAndSendWebInputEvent(wheel_event.event, wheel_event.latency, false); + FilterAndSendWebInputEvent(wheel_event.event, wheel_event.latency); } void InputRouterImpl::SendKeyboardEvent( - const NativeWebKeyboardEventWithLatencyInfo& key_event, - bool is_keyboard_shortcut) { + const NativeWebKeyboardEventWithLatencyInfo& key_event) { // Put all WebKeyboardEvent objects in a queue since we can't trust the // renderer and we need to give something to the HandleKeyboardEvent // handler. @@ -167,9 +166,7 @@ gesture_event_queue_.FlingHasBeenHalted(); // Only forward the non-native portions of our event. - FilterAndSendWebInputEvent(key_event.event, - key_event.latency, - is_keyboard_shortcut); + FilterAndSendWebInputEvent(key_event.event, key_event.latency); } void InputRouterImpl::SendGestureEvent( @@ -213,7 +210,7 @@ current_mouse_move_ = mouse_event; } - FilterAndSendWebInputEvent(mouse_event.event, mouse_event.latency, false); + FilterAndSendWebInputEvent(mouse_event.event, mouse_event.latency); } void InputRouterImpl::SendTouchEventImmediately( @@ -227,12 +224,12 @@ UpdateTouchAckTimeoutEnabled(); } - FilterAndSendWebInputEvent(touch_event.event, touch_event.latency, false); + FilterAndSendWebInputEvent(touch_event.event, touch_event.latency); } void InputRouterImpl::SendGestureEventImmediately( const GestureEventWithLatencyInfo& gesture_event) { - FilterAndSendWebInputEvent(gesture_event.event, gesture_event.latency, false); + FilterAndSendWebInputEvent(gesture_event.event, gesture_event.latency); } const NativeWebKeyboardEvent* InputRouterImpl::GetLastKeyboardEvent() const { @@ -339,8 +336,7 @@ void InputRouterImpl::FilterAndSendWebInputEvent( const WebInputEvent& input_event, - const ui::LatencyInfo& latency_info, - bool is_keyboard_shortcut) { + const ui::LatencyInfo& latency_info) { TRACE_EVENT1("input", "InputRouterImpl::FilterAndSendWebInputEvent", "type", @@ -354,18 +350,17 @@ // Any input event cancels a pending mouse move event. next_mouse_move_.reset(); - OfferToHandlers(input_event, latency_info, is_keyboard_shortcut); + OfferToHandlers(input_event, latency_info); } void InputRouterImpl::OfferToHandlers(const WebInputEvent& input_event, - const ui::LatencyInfo& latency_info, - bool is_keyboard_shortcut) { + const ui::LatencyInfo& latency_info) { output_stream_validator_.Validate(input_event); if (OfferToClient(input_event, latency_info)) return; - OfferToRenderer(input_event, latency_info, is_keyboard_shortcut); + OfferToRenderer(input_event, latency_info); // Touch events should always indicate in the event whether they are // cancelable (respect ACK disposition) or not except touchmove. @@ -416,10 +411,9 @@ } bool InputRouterImpl::OfferToRenderer(const WebInputEvent& input_event, - const ui::LatencyInfo& latency_info, - bool is_keyboard_shortcut) { - if (Send(new InputMsg_HandleInputEvent( - routing_id(), &input_event, latency_info, is_keyboard_shortcut))) { + const ui::LatencyInfo& latency_info) { + if (Send(new InputMsg_HandleInputEvent(routing_id(), &input_event, + latency_info))) { // Ack messages for ignored ack event types should never be sent by the // renderer. Consequently, such event types should not affect event time // or in-flight event count metrics.
diff --git a/content/browser/renderer_host/input/input_router_impl.h b/content/browser/renderer_host/input/input_router_impl.h index f42adfade..e1ea09a 100644 --- a/content/browser/renderer_host/input/input_router_impl.h +++ b/content/browser/renderer_host/input/input_router_impl.h
@@ -59,8 +59,8 @@ void SendMouseEvent(const MouseEventWithLatencyInfo& mouse_event) override; void SendWheelEvent( const MouseWheelEventWithLatencyInfo& wheel_event) override; - void SendKeyboardEvent(const NativeWebKeyboardEventWithLatencyInfo& key_event, - bool is_keyboard_shortcut) override; + void SendKeyboardEvent( + const NativeWebKeyboardEventWithLatencyInfo& key_event) override; void SendGestureEvent( const GestureEventWithLatencyInfo& gesture_event) override; void SendTouchEvent(const TouchEventWithLatencyInfo& touch_event) override; @@ -97,19 +97,13 @@ // Filters and forwards |input_event| to the appropriate handler. void FilterAndSendWebInputEvent(const blink::WebInputEvent& input_event, - const ui::LatencyInfo& latency_info, - bool is_keyboard_shortcut); + const ui::LatencyInfo& latency_info); // Utility routine for filtering and forwarding |input_event| to the // appropriate handler. |input_event| will be offered to the overscroll // controller, client and renderer, in that order. void OfferToHandlers(const blink::WebInputEvent& input_event, - const ui::LatencyInfo& latency_info, - bool is_keyboard_shortcut); - - // Returns true if |input_event| was consumed by the overscroll controller. - bool OfferToOverscrollController(const blink::WebInputEvent& input_event, - const ui::LatencyInfo& latency_info); + const ui::LatencyInfo& latency_info); // Returns true if |input_event| was consumed by the client. bool OfferToClient(const blink::WebInputEvent& input_event, @@ -118,8 +112,7 @@ // Returns true if |input_event| was successfully sent to the renderer // as an async IPC Message. bool OfferToRenderer(const blink::WebInputEvent& input_event, - const ui::LatencyInfo& latency_info, - bool is_keyboard_shortcut); + const ui::LatencyInfo& latency_info); // IPC message handlers void OnInputEventAck(const InputEventAck& ack);
diff --git a/content/browser/renderer_host/input/input_router_impl_unittest.cc b/content/browser/renderer_host/input/input_router_impl_unittest.cc index a7b1ba9..2290860 100644 --- a/content/browser/renderer_host/input/input_router_impl_unittest.cc +++ b/content/browser/renderer_host/input/input_router_impl_unittest.cc
@@ -80,12 +80,6 @@ return *event; } -bool GetIsShortcutFromHandleInputEventMessage(const IPC::Message* msg) { - InputMsg_HandleInputEvent::Schema::Param param; - InputMsg_HandleInputEvent::Read(msg, ¶m); - return base::get<2>(param); -} - template<typename MSG_T, typename ARG_T1> void ExpectIPCMessageWithArg1(const IPC::Message* msg, const ARG_T1& arg1) { ASSERT_EQ(MSG_T::ID, msg->type()); @@ -182,12 +176,12 @@ input_router()->NotifySiteIsMobileOptimized(false); } - void SimulateKeyboardEvent(WebInputEvent::Type type, bool is_shortcut) { + void SimulateKeyboardEvent(WebInputEvent::Type type) { WebKeyboardEvent event = SyntheticWebKeyboardEventBuilder::Build(type); NativeWebKeyboardEvent native_event; memcpy(&native_event, &event, sizeof(event)); NativeWebKeyboardEventWithLatencyInfo key_event(native_event); - input_router_->SendKeyboardEvent(key_event, is_shortcut); + input_router_->SendKeyboardEvent(key_event); } void SimulateWheelEvent(float dX, float dY, int modifiers, bool precise) { @@ -617,7 +611,7 @@ client_->set_filter_state(INPUT_EVENT_ACK_STATE_CONSUMED); // Simulate a keyboard event. - SimulateKeyboardEvent(WebInputEvent::RawKeyDown, false); + SimulateKeyboardEvent(WebInputEvent::RawKeyDown); // Make sure no input event is sent to the renderer. EXPECT_EQ(0u, GetSentMessageCountAndResetSink()); @@ -634,7 +628,7 @@ client_->set_filter_state(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS); // Simulate a keyboard event that has no consumer. - SimulateKeyboardEvent(WebInputEvent::RawKeyDown, false); + SimulateKeyboardEvent(WebInputEvent::RawKeyDown); // Make sure no input event is sent to the renderer. EXPECT_EQ(0u, GetSentMessageCountAndResetSink()); @@ -643,27 +637,15 @@ // Simulate a keyboard event that should be dropped. client_->set_filter_state(INPUT_EVENT_ACK_STATE_UNKNOWN); - SimulateKeyboardEvent(WebInputEvent::RawKeyDown, false); + SimulateKeyboardEvent(WebInputEvent::RawKeyDown); // Make sure no input event is sent to the renderer, and no ack is sent. EXPECT_EQ(0u, GetSentMessageCountAndResetSink()); EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount()); } -TEST_F(InputRouterImplTest, ShortcutKeyboardEvent) { - SimulateKeyboardEvent(WebInputEvent::RawKeyDown, true); - EXPECT_TRUE(GetIsShortcutFromHandleInputEventMessage( - process_->sink().GetMessageAt(0))); - - process_->sink().ClearMessages(); - - SimulateKeyboardEvent(WebInputEvent::RawKeyDown, false); - EXPECT_FALSE(GetIsShortcutFromHandleInputEventMessage( - process_->sink().GetMessageAt(0))); -} - TEST_F(InputRouterImplTest, NoncorrespondingKeyEvents) { - SimulateKeyboardEvent(WebInputEvent::RawKeyDown, false); + SimulateKeyboardEvent(WebInputEvent::RawKeyDown); SendInputEventACK(WebInputEvent::KeyUp, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); @@ -674,7 +656,7 @@ TEST_F(InputRouterImplTest, HandleKeyEventsWeSent) { // Simulate a keyboard event. - SimulateKeyboardEvent(WebInputEvent::RawKeyDown, false); + SimulateKeyboardEvent(WebInputEvent::RawKeyDown); ASSERT_TRUE(input_router_->GetLastKeyboardEvent()); EXPECT_EQ(WebInputEvent::RawKeyDown, input_router_->GetLastKeyboardEvent()->type);
diff --git a/content/browser/renderer_host/input/mock_input_router_client.cc b/content/browser/renderer_host/input/mock_input_router_client.cc index fcb5de1..07d3d179 100644 --- a/content/browser/renderer_host/input/mock_input_router_client.cc +++ b/content/browser/renderer_host/input/mock_input_router_client.cc
@@ -33,7 +33,7 @@ const WebInputEvent& input_event, const ui::LatencyInfo& latency_info) { filter_input_event_called_ = true; - last_filter_event_.reset(new InputEvent(input_event, latency_info, false)); + last_filter_event_.reset(new InputEvent(input_event, latency_info)); return filter_state_; }
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 8b96d457..c89173a 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -1351,6 +1351,7 @@ switches::kVModule, // Please keep these in alphabetical order. Compositor switches here should // also be added to chrome/browser/chromeos/login/chrome_restart_request.cc. + cc::switches::kDisableCachedPictureRaster, cc::switches::kDisableCompositedAntialiasing, cc::switches::kDisableMainFrameBeforeActivation, cc::switches::kDisableThreadedAnimation, @@ -1705,6 +1706,17 @@ DCHECK(!deleting_soon_); DCHECK_EQ(0, pending_views_); + + // If |channel_| is still valid, the process associated with this + // RenderProcessHost is still alive. Notify all observers that the process + // has exited cleanly, even though it will be destroyed a bit later. + // Observers shouldn't rely on this process anymore. + if (channel_.get()) { + FOR_EACH_OBSERVER( + RenderProcessHostObserver, observers_, + RenderProcessExited(this, base::TERMINATION_STATUS_NORMAL_TERMINATION, + 0)); + } FOR_EACH_OBSERVER(RenderProcessHostObserver, observers_, RenderProcessHostDestroyed(this)); NotificationService::current()->Notify( @@ -1729,6 +1741,14 @@ RemoveUserData(kSessionStorageHolderKey); + // On shutdown, |this| may not be deleted because the deleter is posted to + // the current MessageLoop, but MessageLoop deletes all its pending + // callbacks on shutdown. Since the deleter takes |this| as a raw pointer, + // deleting the callback doesn't delete |this| resulting in a memory leak. + // Valgrind complains, so delete |mojo_application_host_| explicitly here to + // stop valgrind from complaining. + mojo_application_host_.reset(); + // Remove ourself from the list of renderer processes so that we can't be // reused in between now and when the Delete task runs. UnregisterHost(GetID());
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc index 512dfee..0b86c70 100644 --- a/content/browser/renderer_host/render_widget_host_impl.cc +++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -1145,8 +1145,9 @@ return; NativeWebKeyboardEventWithLatencyInfo key_event_with_latency(key_event); + key_event_with_latency.event.isBrowserShortcut = is_shortcut; latency_tracker_.OnInputEvent(key_event, &key_event_with_latency.latency); - input_router_->SendKeyboardEvent(key_event_with_latency, is_shortcut); + input_router_->SendKeyboardEvent(key_event_with_latency); } void RenderWidgetHostImpl::QueueSyntheticGesture(
diff --git a/content/browser/renderer_host/render_widget_host_unittest.cc b/content/browser/renderer_host/render_widget_host_unittest.cc index 2503b5e..9d95b9a 100644 --- a/content/browser/renderer_host/render_widget_host_unittest.cc +++ b/content/browser/renderer_host/render_widget_host_unittest.cc
@@ -55,6 +55,22 @@ namespace content { +std::string GetInputMessageTypes(MockRenderProcessHost* process) { + std::string result; + for (size_t i = 0; i < process->sink().message_count(); ++i) { + const IPC::Message* message = process->sink().GetMessageAt(i); + EXPECT_EQ(InputMsg_HandleInputEvent::ID, message->type()); + InputMsg_HandleInputEvent::Param params; + EXPECT_TRUE(InputMsg_HandleInputEvent::Read(message, ¶ms)); + const WebInputEvent* event = base::get<0>(params); + if (i != 0) + result += " "; + result += WebInputEventTraits::GetName(event->type); + } + process->sink().ClearMessages(); + return result; +} + // MockInputRouter ------------------------------------------------------------- class MockInputRouter : public InputRouter { @@ -83,8 +99,8 @@ const MouseWheelEventWithLatencyInfo& wheel_event) override { sent_wheel_event_ = true; } - void SendKeyboardEvent(const NativeWebKeyboardEventWithLatencyInfo& key_event, - bool is_shortcut) override { + void SendKeyboardEvent( + const NativeWebKeyboardEventWithLatencyInfo& key_event) override { sent_keyboard_event_ = true; } void SendGestureEvent( @@ -327,13 +343,13 @@ public: MockRenderWidgetHostDelegate() : prehandle_keyboard_event_(false), + prehandle_keyboard_event_is_shortcut_(false), prehandle_keyboard_event_called_(false), prehandle_keyboard_event_type_(WebInputEvent::Undefined), unhandled_keyboard_event_called_(false), unhandled_keyboard_event_type_(WebInputEvent::Undefined), handle_wheel_event_(false), - handle_wheel_event_called_(false) { - } + handle_wheel_event_called_(false) {} ~MockRenderWidgetHostDelegate() override {} // Tests that make sure we ignore keyboard event acknowledgments to events we @@ -362,15 +378,18 @@ handle_wheel_event_ = handle; } - bool handle_wheel_event_called() { - return handle_wheel_event_called_; + void set_prehandle_keyboard_event_is_shortcut(bool is_shortcut) { + prehandle_keyboard_event_is_shortcut_ = is_shortcut; } + bool handle_wheel_event_called() const { return handle_wheel_event_called_; } + protected: bool PreHandleKeyboardEvent(const NativeWebKeyboardEvent& event, bool* is_keyboard_shortcut) override { prehandle_keyboard_event_type_ = event.type; prehandle_keyboard_event_called_ = true; + *is_keyboard_shortcut = prehandle_keyboard_event_is_shortcut_; return prehandle_keyboard_event_; } @@ -391,6 +410,7 @@ private: bool prehandle_keyboard_event_; + bool prehandle_keyboard_event_is_shortcut_; bool prehandle_keyboard_event_called_; WebInputEvent::Type prehandle_keyboard_event_type_; @@ -891,7 +911,7 @@ } TEST_F(RenderWidgetHostTest, PreHandleRawKeyDownEvent) { - // Simluate the situation that the browser handled the key down event during + // Simulate the situation that the browser handled the key down event during // pre-handle phrase. delegate_->set_prehandle_keyboard_event(true); process_->sink().ClearMessages(); @@ -932,6 +952,59 @@ EXPECT_EQ(WebInputEvent::KeyUp, delegate_->unhandled_keyboard_event_type()); } +TEST_F(RenderWidgetHostTest, RawKeyDownShortcutEvent) { + // Simulate the situation that the browser marks the key down as a keyboard + // shortcut, but doesn't consume it in the pre-handle phase. + delegate_->set_prehandle_keyboard_event_is_shortcut(true); + process_->sink().ClearMessages(); + + // Simulate a keyboard event. + SimulateKeyboardEvent(WebInputEvent::RawKeyDown); + + EXPECT_TRUE(delegate_->prehandle_keyboard_event_called()); + EXPECT_EQ(WebInputEvent::RawKeyDown, + delegate_->prehandle_keyboard_event_type()); + + // Make sure the RawKeyDown event is sent to the renderer. + EXPECT_EQ(1U, process_->sink().message_count()); + EXPECT_EQ("RawKeyDown", GetInputMessageTypes(process_)); + process_->sink().ClearMessages(); + + // Send the simulated response from the renderer back. + SendInputEventACK(WebInputEvent::RawKeyDown, + INPUT_EVENT_ACK_STATE_NOT_CONSUMED); + EXPECT_EQ(WebInputEvent::RawKeyDown, + delegate_->unhandled_keyboard_event_type()); + + // The browser won't pre-handle a Char event. + delegate_->set_prehandle_keyboard_event_is_shortcut(false); + + // Forward the Char event. + SimulateKeyboardEvent(WebInputEvent::Char); + + // The Char event is not suppressed; the renderer will ignore it + // if the preceding RawKeyDown shortcut goes unhandled. + EXPECT_EQ(1U, process_->sink().message_count()); + EXPECT_EQ("Char", GetInputMessageTypes(process_)); + process_->sink().ClearMessages(); + + // Send the simulated response from the renderer back. + SendInputEventACK(WebInputEvent::Char, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); + EXPECT_EQ(WebInputEvent::Char, delegate_->unhandled_keyboard_event_type()); + + // Forward the KeyUp event. + SimulateKeyboardEvent(WebInputEvent::KeyUp); + + // Make sure only KeyUp was sent to the renderer. + EXPECT_EQ(1U, process_->sink().message_count()); + EXPECT_EQ("KeyUp", GetInputMessageTypes(process_)); + process_->sink().ClearMessages(); + + // Send the simulated response from the renderer back. + SendInputEventACK(WebInputEvent::KeyUp, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); + EXPECT_EQ(WebInputEvent::KeyUp, delegate_->unhandled_keyboard_event_type()); +} + TEST_F(RenderWidgetHostTest, UnhandledWheelEvent) { SimulateWheelEvent(-5, 0, 0, true); @@ -1134,22 +1207,6 @@ EXPECT_TRUE(host_->new_content_rendering_timeout_fired()); } -std::string GetInputMessageTypes(RenderWidgetHostProcess* process) { - std::string result; - for (size_t i = 0; i < process->sink().message_count(); ++i) { - const IPC::Message *message = process->sink().GetMessageAt(i); - EXPECT_EQ(InputMsg_HandleInputEvent::ID, message->type()); - InputMsg_HandleInputEvent::Param params; - EXPECT_TRUE(InputMsg_HandleInputEvent::Read(message, ¶ms)); - const WebInputEvent* event = base::get<0>(params); - if (i != 0) - result += " "; - result += WebInputEventTraits::GetName(event->type); - } - process->sink().ClearMessages(); - return result; -} - TEST_F(RenderWidgetHostTest, TouchEmulator) { simulated_event_time_delta_seconds_ = 0.1; // Immediately ack all touches instead of sending them to the renderer.
diff --git a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc index 0b09f0f..9145cc0 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
@@ -21,6 +21,7 @@ #include "content/browser/compositor/resize_lock.h" #include "content/browser/compositor/test/no_transport_image_transport_factory.h" #include "content/browser/frame_host/render_widget_host_view_guest.h" +#include "content/browser/gpu/compositor_util.h" #include "content/browser/renderer_host/input/input_router.h" #include "content/browser/renderer_host/input/web_input_event_util.h" #include "content/browser/renderer_host/overscroll_controller.h" @@ -192,12 +193,14 @@ class FakeFrameSubscriber : public RenderWidgetHostViewFrameSubscriber { public: FakeFrameSubscriber(gfx::Size size, base::Callback<void(bool)> callback) - : size_(size), callback_(callback) {} + : size_(size), callback_(callback), should_capture_(true) {} bool ShouldCaptureFrame(const gfx::Rect& damage_rect, base::TimeTicks present_time, scoped_refptr<media::VideoFrame>* storage, DeliverFrameCallback* callback) override { + if (!should_capture_) + return false; last_present_time_ = present_time; *storage = media::VideoFrame::CreateFrame(media::PIXEL_FORMAT_YV12, size_, gfx::Rect(size_), size_, @@ -208,6 +211,10 @@ base::TimeTicks last_present_time() const { return last_present_time_; } + void set_should_capture(bool should_capture) { + should_capture_ = should_capture; + } + static void CallbackMethod(base::Callback<void(bool)> callback, base::TimeTicks present_time, bool success) { @@ -218,6 +225,7 @@ gfx::Size size_; base::Callback<void(bool)> callback_; base::TimeTicks last_present_time_; + bool should_capture_; }; class FakeWindowEventDispatcher : public aura::WindowEventDispatcher { @@ -2236,7 +2244,10 @@ void RunLoopUntilCallback() { base::RunLoop run_loop; quit_closure_ = run_loop.QuitClosure(); + // Temporarily ignore real draw requests. + frame_subscriber_->set_should_capture(false); run_loop.Run(); + frame_subscriber_->set_should_capture(true); } void InitializeView() { @@ -2268,6 +2279,10 @@ void OnSwapCompositorFrame() { view_->OnSwapCompositorFrame( 1, MakeDelegatedFrame(1.f, view_rect_.size(), view_rect_)); + cc::SurfaceId surface_id = + view_->GetDelegatedFrameHost()->SurfaceIdForTesting(); + if (!surface_id.is_null()) + view_->GetDelegatedFrameHost()->WillDrawSurface(surface_id, view_rect_); ASSERT_TRUE(view_->last_copy_request_); }
diff --git a/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm b/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm index 5a0ec418..7a5afa3 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm +++ b/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm
@@ -927,7 +927,7 @@ break; } DCHECK(message); - base::Tuple<IPC::WebInputEventPointer, ui::LatencyInfo, bool> data; + base::Tuple<IPC::WebInputEventPointer, ui::LatencyInfo> data; InputMsg_HandleInputEvent::Read(message, &data); IPC::WebInputEventPointer ipc_event = base::get<0>(data); const blink::WebGestureEvent* gesture_event =
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc index 0896a67..22d3500e1 100644 --- a/content/browser/site_per_process_browsertest.cc +++ b/content/browser/site_per_process_browsertest.cc
@@ -24,6 +24,7 @@ #include "content/browser/renderer_host/render_widget_host_input_event_router.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/common/frame_messages.h" +#include "content/common/view_messages.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_types.h" @@ -3515,4 +3516,85 @@ EXPECT_EQ(root, root->frame_tree()->GetFocusedFrame()); } +// There are no cursors on Android. +#if !defined(OS_ANDROID) +class CursorMessageFilter : public content::BrowserMessageFilter { + public: + CursorMessageFilter() + : content::BrowserMessageFilter(ViewMsgStart), + message_loop_runner_(new content::MessageLoopRunner), + last_set_cursor_routing_id_(MSG_ROUTING_NONE) {} + + bool OnMessageReceived(const IPC::Message& message) override { + if (message.type() == ViewHostMsg_SetCursor::ID) { + content::BrowserThread::PostTask( + content::BrowserThread::UI, FROM_HERE, + base::Bind(&CursorMessageFilter::OnSetCursor, this, + message.routing_id())); + } + return false; + } + + void OnSetCursor(int routing_id) { + last_set_cursor_routing_id_ = routing_id; + message_loop_runner_->Quit(); + } + + int last_set_cursor_routing_id() const { return last_set_cursor_routing_id_; } + + void Wait() { + last_set_cursor_routing_id_ = MSG_ROUTING_NONE; + message_loop_runner_->Run(); + } + + private: + ~CursorMessageFilter() override {} + + scoped_refptr<content::MessageLoopRunner> message_loop_runner_; + int last_set_cursor_routing_id_; + + DISALLOW_COPY_AND_ASSIGN(CursorMessageFilter); +}; + +// Verify that we receive a mouse cursor update message when we mouse over +// a text field contained in an out-of-process iframe. +IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, + CursorUpdateFromReceivedFromCrossSiteIframe) { + GURL main_url(embedded_test_server()->GetURL( + "/frame_tree/page_with_positioned_frame.html")); + EXPECT_TRUE(NavigateToURL(shell(), main_url)); + + FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) + ->GetFrameTree() + ->root(); + + FrameTreeNode* child_node = root->child_at(0); + EXPECT_NE(shell()->web_contents()->GetSiteInstance(), + child_node->current_frame_host()->GetSiteInstance()); + + scoped_refptr<CursorMessageFilter> filter = new CursorMessageFilter(); + child_node->current_frame_host()->GetProcess()->AddFilter(filter.get()); + + // Send a MouseMove to the subframe. The frame contains text, and moving the + // mouse over it should cause the renderer to send a mouse cursor update. + blink::WebMouseEvent mouse_event; + mouse_event.type = blink::WebInputEvent::MouseMove; + mouse_event.x = 60; + mouse_event.y = 60; + RenderWidgetHost* rwh_child = + root->child_at(0)->current_frame_host()->GetRenderWidgetHost(); + RenderWidgetHostViewBase* root_view = static_cast<RenderWidgetHostViewBase*>( + root->current_frame_host()->GetRenderWidgetHost()->GetView()); + static_cast<WebContentsImpl*>(shell()->web_contents()) + ->GetInputEventRouter() + ->RouteMouseEvent(root_view, &mouse_event); + + // CursorMessageFilter::Wait() implicitly tests whether we receive a + // ViewHostMsg_SetCursor message from the renderer process, because it does + // does not return otherwise. + filter->Wait(); + EXPECT_EQ(filter->last_set_cursor_routing_id(), rwh_child->GetRoutingID()); +} +#endif + } // namespace content
diff --git a/content/common/input/input_event.cc b/content/common/input/input_event.cc index 93e96911..ab20010 100644 --- a/content/common/input/input_event.cc +++ b/content/common/input/input_event.cc
@@ -8,14 +8,12 @@ namespace content { -InputEvent::InputEvent() : is_keyboard_shortcut(false) {} +InputEvent::InputEvent() {} InputEvent::InputEvent(const blink::WebInputEvent& web_event, - const ui::LatencyInfo& latency_info, - bool is_keyboard_shortcut) - : web_event(WebInputEventTraits::Clone(web_event)), - latency_info(latency_info), - is_keyboard_shortcut(is_keyboard_shortcut) {} + const ui::LatencyInfo& latency_info) + : web_event(WebInputEventTraits::Clone(web_event)), + latency_info(latency_info) {} InputEvent::~InputEvent() {}
diff --git a/content/common/input/input_event.h b/content/common/input/input_event.h index 4c13e061..71a3f2b 100644 --- a/content/common/input/input_event.h +++ b/content/common/input/input_event.h
@@ -22,13 +22,11 @@ public: InputEvent(); InputEvent(const blink::WebInputEvent& web_event, - const ui::LatencyInfo& latency_info, - bool is_keyboard_shortcut); + const ui::LatencyInfo& latency_info); ~InputEvent(); ScopedWebInputEvent web_event; ui::LatencyInfo latency_info; - bool is_keyboard_shortcut; private: DISALLOW_COPY_AND_ASSIGN(InputEvent);
diff --git a/content/common/input/input_param_traits_unittest.cc b/content/common/input/input_param_traits_unittest.cc index 784278a..238aff7c 100644 --- a/content/common/input/input_param_traits_unittest.cc +++ b/content/common/input/input_param_traits_unittest.cc
@@ -30,7 +30,6 @@ } EXPECT_EQ(a->latency_info.latency_components().size(), b->latency_info.latency_components().size()); - EXPECT_EQ(a->is_keyboard_shortcut, b->is_keyboard_shortcut); } static void Compare(const InputEvents* a, const InputEvents* b) { @@ -163,30 +162,30 @@ blink::WebKeyboardEvent key_event; key_event.type = blink::WebInputEvent::RawKeyDown; key_event.nativeKeyCode = 5; - events.push_back(new InputEvent(key_event, latency, false)); + events.push_back(new InputEvent(key_event, latency)); blink::WebMouseWheelEvent wheel_event; wheel_event.type = blink::WebInputEvent::MouseWheel; wheel_event.deltaX = 10; latency.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, 1, 1); - events.push_back(new InputEvent(wheel_event, latency, false)); + events.push_back(new InputEvent(wheel_event, latency)); blink::WebMouseEvent mouse_event; mouse_event.type = blink::WebInputEvent::MouseDown; mouse_event.x = 10; latency.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_UI_COMPONENT, 2, 2); - events.push_back(new InputEvent(mouse_event, latency, false)); + events.push_back(new InputEvent(mouse_event, latency)); blink::WebGestureEvent gesture_event; gesture_event.type = blink::WebInputEvent::GestureScrollBegin; gesture_event.x = -1; - events.push_back(new InputEvent(gesture_event, latency, false)); + events.push_back(new InputEvent(gesture_event, latency)); blink::WebTouchEvent touch_event; touch_event.type = blink::WebInputEvent::TouchStart; touch_event.touchesLength = 1; touch_event.touches[0].radiusX = 1; - events.push_back(new InputEvent(touch_event, latency, false)); + events.push_back(new InputEvent(touch_event, latency)); Verify(events); }
diff --git a/content/common/input_messages.h b/content/common/input_messages.h index 85796f71..b7bb586a 100644 --- a/content/common/input_messages.h +++ b/content/common/input_messages.h
@@ -72,7 +72,6 @@ IPC_STRUCT_TRAITS_BEGIN(content::InputEvent) IPC_STRUCT_TRAITS_MEMBER(web_event) IPC_STRUCT_TRAITS_MEMBER(latency_info) - IPC_STRUCT_TRAITS_MEMBER(is_keyboard_shortcut) IPC_STRUCT_TRAITS_END() IPC_STRUCT_TRAITS_BEGIN(content::SyntheticGestureParams) @@ -116,10 +115,9 @@ IPC_STRUCT_TRAITS_END() // Sends an input event to the render widget. -IPC_MESSAGE_ROUTED3(InputMsg_HandleInputEvent, +IPC_MESSAGE_ROUTED2(InputMsg_HandleInputEvent, IPC::WebInputEventPointer /* event */, - ui::LatencyInfo /* latency_info */, - bool /* is_keyboard_shortcut */) + ui::LatencyInfo /* latency_info */) // Sends the cursor visibility state to the render widget. IPC_MESSAGE_ROUTED1(InputMsg_CursorVisibilityChange,
diff --git a/content/content_shell.gypi b/content/content_shell.gypi index 212ba04a..e170e34 100644 --- a/content/content_shell.gypi +++ b/content/content_shell.gypi
@@ -215,8 +215,6 @@ 'shell/renderer/layout_test/blink_test_helpers.h', 'shell/renderer/layout_test/blink_test_runner.cc', 'shell/renderer/layout_test/blink_test_runner.h', - 'shell/renderer/layout_test/gc_controller.cc', - 'shell/renderer/layout_test/gc_controller.h', 'shell/renderer/layout_test/layout_test_content_renderer_client.cc', 'shell/renderer/layout_test/layout_test_content_renderer_client.h', 'shell/renderer/layout_test/layout_test_render_frame_observer.cc',
diff --git a/content/public/android/java/src/org/chromium/content/app/ChildProcessService.java b/content/public/android/java/src/org/chromium/content/app/ChildProcessService.java index e6f6bc0..a5bced2 100644 --- a/content/public/android/java/src/org/chromium/content/app/ChildProcessService.java +++ b/content/public/android/java/src/org/chromium/content/app/ChildProcessService.java
@@ -333,7 +333,7 @@ try { return mCallback.getViewSurface(surfaceId).getSurface(); } catch (RemoteException e) { - Log.e(TAG, "Unable to call establishSurfaceTexturePeer: %s", e); + Log.e(TAG, "Unable to call getViewSurface: %s", e); return null; } }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ContentViewCoreSelectionTest.java b/content/public/android/javatests/src/org/chromium/content/browser/ContentViewCoreSelectionTest.java index 932d4a4..1817443 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/ContentViewCoreSelectionTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/ContentViewCoreSelectionTest.java
@@ -12,6 +12,7 @@ import android.text.TextUtils; import org.chromium.base.ThreadUtils; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.UrlUtils; import org.chromium.content.browser.test.util.Criteria; @@ -175,6 +176,7 @@ assertWaitForPastePopupStatus(false); } + @DisabledTest // http://crbug.com/543682 @SmallTest @Feature({"TextInput"}) public void testPastePopupNotShownOnLongPressingReadOnlyInput() throws Throwable {
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc index ace7157..6497faf 100644 --- a/content/public/common/content_switches.cc +++ b/content/public/common/content_switches.cc
@@ -83,10 +83,6 @@ // features. const char kDisableBlinkFeatures[] = "disable-blink-features"; -// Disable the creation of compositing layers when it would prevent LCD text. -const char kDisablePreferCompositingToLCDText[] = - "disable-prefer-compositing-to-lcd-text"; - // Disables HTML5 DB support. const char kDisableDatabases[] = "disable-databases"; @@ -216,6 +212,10 @@ // --extra-plugin-dir and --load-plugin switches. const char kDisablePluginsDiscovery[] = "disable-plugins-discovery"; +// Disable the creation of compositing layers when it would prevent LCD text. +const char kDisablePreferCompositingToLCDText[] = + "disable-prefer-compositing-to-lcd-text"; + // Disables the Presentation API. const char kDisablePresentationAPI[] = "disable-presentation-api";
diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h index 5d47e85..32a67e04 100644 --- a/content/public/common/content_switches.h +++ b/content/public/common/content_switches.h
@@ -34,7 +34,6 @@ CONTENT_EXPORT extern const char kDisableAcceleratedMjpegDecode[]; CONTENT_EXPORT extern const char kDisableAcceleratedVideoDecode[]; extern const char kDisableBackingStoreLimit[]; -CONTENT_EXPORT extern const char kDisablePreferCompositingToLCDText[]; CONTENT_EXPORT extern const char kDisableDatabases[]; CONTENT_EXPORT extern const char kDisableDelayAgnosticAec[]; extern const char kDisableDirectNPAPIRequests[]; @@ -60,6 +59,7 @@ CONTENT_EXPORT extern const char kDisableHideInactiveStackedTabCloseButtons[]; extern const char kDisableHistogramCustomizer[]; CONTENT_EXPORT extern const char kDisableLCDText[]; +CONTENT_EXPORT extern const char kDisablePreferCompositingToLCDText[]; CONTENT_EXPORT extern const char kEnablePrefixedEncryptedMedia[]; extern const char kDisableKillAfterBadIPC[]; CONTENT_EXPORT extern const char kDisableLocalStorage[];
diff --git a/content/public/test/render_view_test.cc b/content/public/test/render_view_test.cc index 4c14407..c465364e 100644 --- a/content/public/test/render_view_test.cc +++ b/content/public/test/render_view_test.cc
@@ -318,14 +318,14 @@ const blink::WebKeyboardEvent& key_event) { RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_); impl->OnMessageReceived( - InputMsg_HandleInputEvent(0, &key_event, ui::LatencyInfo(), false)); + InputMsg_HandleInputEvent(0, &key_event, ui::LatencyInfo())); } void RenderViewTest::SendWebMouseEvent( const blink::WebMouseEvent& mouse_event) { RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_); impl->OnMessageReceived( - InputMsg_HandleInputEvent(0, &mouse_event, ui::LatencyInfo(), false)); + InputMsg_HandleInputEvent(0, &mouse_event, ui::LatencyInfo())); } const char* const kGetCoordinatesScript = @@ -392,10 +392,10 @@ mouse_event.clickCount = 1; RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_); impl->OnMessageReceived( - InputMsg_HandleInputEvent(0, &mouse_event, ui::LatencyInfo(), false)); + InputMsg_HandleInputEvent(0, &mouse_event, ui::LatencyInfo())); mouse_event.type = WebInputEvent::MouseUp; impl->OnMessageReceived( - InputMsg_HandleInputEvent(0, &mouse_event, ui::LatencyInfo(), false)); + InputMsg_HandleInputEvent(0, &mouse_event, ui::LatencyInfo())); } @@ -416,10 +416,10 @@ mouse_event.clickCount = 1; RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_); impl->OnMessageReceived( - InputMsg_HandleInputEvent(0, &mouse_event, ui::LatencyInfo(), false)); + InputMsg_HandleInputEvent(0, &mouse_event, ui::LatencyInfo())); mouse_event.type = WebInputEvent::MouseUp; impl->OnMessageReceived( - InputMsg_HandleInputEvent(0, &mouse_event, ui::LatencyInfo(), false)); + InputMsg_HandleInputEvent(0, &mouse_event, ui::LatencyInfo())); } void RenderViewTest::SimulateRectTap(const gfx::Rect& rect) { @@ -432,7 +432,7 @@ gesture_event.type = WebInputEvent::GestureTap; RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_); impl->OnMessageReceived( - InputMsg_HandleInputEvent(0, &gesture_event, ui::LatencyInfo(), false)); + InputMsg_HandleInputEvent(0, &gesture_event, ui::LatencyInfo())); impl->FocusChangeComplete(); }
diff --git a/content/renderer/idle_user_detector.cc b/content/renderer/idle_user_detector.cc index dff78d1..339f68a 100644 --- a/content/renderer/idle_user_detector.cc +++ b/content/renderer/idle_user_detector.cc
@@ -26,8 +26,7 @@ } void IdleUserDetector::OnHandleInputEvent(const blink::WebInputEvent* event, - const ui::LatencyInfo& latency_info, - bool is_keyboard_shortcut) { + const ui::LatencyInfo& latency_info) { if (GetContentClient()->renderer()->RunIdleHandlerWhenWidgetsHidden()) { RenderThreadImpl* render_thread = RenderThreadImpl::current(); if (render_thread != NULL) {
diff --git a/content/renderer/idle_user_detector.h b/content/renderer/idle_user_detector.h index 054ead8..58e7037 100644 --- a/content/renderer/idle_user_detector.h +++ b/content/renderer/idle_user_detector.h
@@ -30,8 +30,7 @@ bool OnMessageReceived(const IPC::Message& message) override; void OnHandleInputEvent(const blink::WebInputEvent* event, - const ui::LatencyInfo& latency_info, - bool is_keyboard_shortcut); + const ui::LatencyInfo& latency_info); DISALLOW_COPY_AND_ASSIGN(IdleUserDetector); };
diff --git a/content/renderer/input/input_event_filter.cc b/content/renderer/input/input_event_filter.cc index 931b4e7..6b648c7 100644 --- a/content/renderer/input/input_event_filter.cc +++ b/content/renderer/input/input_event_filter.cc
@@ -147,7 +147,6 @@ return; const WebInputEvent* event = base::get<0>(params); ui::LatencyInfo latency_info = base::get<1>(params); - bool is_keyboard_shortcut = base::get<2>(params); DCHECK(event); const bool send_ack = WebInputEventTraits::WillReceiveAckFromRenderer(*event); @@ -167,8 +166,8 @@ "input", "InputEventFilter::ForwardToHandler::ForwardToMainListener", TRACE_EVENT_SCOPE_THREAD); - IPC::Message new_msg = InputMsg_HandleInputEvent( - routing_id, event, latency_info, is_keyboard_shortcut); + IPC::Message new_msg = + InputMsg_HandleInputEvent(routing_id, event, latency_info); main_task_runner_->PostTask(FROM_HERE, base::Bind(main_listener_, new_msg)); return; }
diff --git a/content/renderer/input/input_event_filter_unittest.cc b/content/renderer/input/input_event_filter_unittest.cc index e96cd7a..d072303 100644 --- a/content/renderer/input/input_event_filter_unittest.cc +++ b/content/renderer/input/input_event_filter_unittest.cc
@@ -113,9 +113,8 @@ size_t count) { std::vector<IPC::Message> messages; for (size_t i = 0; i < count; ++i) { - messages.push_back( - InputMsg_HandleInputEvent( - kTestRoutingID, &events[i], ui::LatencyInfo(), false)); + messages.push_back(InputMsg_HandleInputEvent(kTestRoutingID, &events[i], + ui::LatencyInfo())); } AddMessagesToFilter(message_filter, messages); @@ -251,10 +250,8 @@ SyntheticWebMouseEventBuilder::Build(WebMouseEvent::MouseUp); std::vector<IPC::Message> messages; - messages.push_back(InputMsg_HandleInputEvent(kTestRoutingID, - &mouse_down, - ui::LatencyInfo(), - false)); + messages.push_back(InputMsg_HandleInputEvent(kTestRoutingID, &mouse_down, + ui::LatencyInfo())); // Control where input events are delivered. messages.push_back(InputMsg_MouseCaptureLost(kTestRoutingID)); messages.push_back(InputMsg_SetFocus(kTestRoutingID, true)); @@ -280,10 +277,8 @@ gfx::Point(), gfx::Point())); messages.push_back(InputMsg_MoveCaret(kTestRoutingID, gfx::Point())); - messages.push_back(InputMsg_HandleInputEvent(kTestRoutingID, - &mouse_up, - ui::LatencyInfo(), - false)); + messages.push_back( + InputMsg_HandleInputEvent(kTestRoutingID, &mouse_up, ui::LatencyInfo())); AddMessagesToFilter(filter_.get(), messages); // We should have sent all messages back to the main thread and preserved
diff --git a/content/renderer/media/android/audio_decoder_android.cc b/content/renderer/media/android/audio_decoder_android.cc index 73a92257..6373ccd 100644 --- a/content/renderer/media/android/audio_decoder_android.cc +++ b/content/renderer/media/android/audio_decoder_android.cc
@@ -481,6 +481,9 @@ file_sample_rate); for (size_t m = 0; m < number_of_samples; m += number_of_channels) { + if (decoded_frames >= number_of_frames) + break; + for (size_t k = 0; k < number_of_channels; ++k) { int16_t sample = decoded_samples[m + k]; destination_bus->channelData(k)[decoded_frames] =
diff --git a/content/renderer/npapi/webplugin_impl.cc b/content/renderer/npapi/webplugin_impl.cc index c611daa..ac739b5 100644 --- a/content/renderer/npapi/webplugin_impl.cc +++ b/content/renderer/npapi/webplugin_impl.cc
@@ -258,8 +258,12 @@ blink::WebPlugin* replacement_plugin = GetContentClient()->renderer()->CreatePluginReplacement( render_frame_, file_path_); - if (!replacement_plugin) + if (!replacement_plugin) { + // Maintain invariant that container() returns null when initialize() + // returns false. + SetContainer(nullptr); return false; + } // Disable scripting by this plugin before replacing it with the new // one. This plugin also needs destroying, so use destroy(), which will
diff --git a/content/renderer/pepper/pepper_webplugin_impl.cc b/content/renderer/pepper/pepper_webplugin_impl.cc index b96bd0c..2773194 100644 --- a/content/renderer/pepper/pepper_webplugin_impl.cc +++ b/content/renderer/pepper/pepper_webplugin_impl.cc
@@ -124,14 +124,22 @@ blink::WebPlugin* replacement_plugin = GetContentClient()->renderer()->CreatePluginReplacement( init_data_->render_frame, init_data_->module->path()); - if (!replacement_plugin || !replacement_plugin->initialize(container)) + if (!replacement_plugin) return false; container->setPlugin(replacement_plugin); + if (!replacement_plugin->initialize(container)) { + CHECK(replacement_plugin->container() == nullptr); + return false; + } + + CHECK(container->plugin() == replacement_plugin); + CHECK(replacement_plugin->container() == container); return true; } init_data_.reset(); + CHECK(container->plugin() == this); container_ = container; return true; }
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index c768e6ae..ace7f67 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc
@@ -1276,6 +1276,11 @@ if (main_frame && main_frame->isWebLocalFrame()) GetContentClient()->SetActiveURL(main_frame->document().url()); + // Input IPC messages must not be processed if the RenderView is in + // swapped out state. + if (is_swapped_out_ && IPC_MESSAGE_ID_CLASS(message.type()) == InputMsgStart) + return false; + base::ObserverListBase<RenderViewObserver>::Iterator it(&observers_); RenderViewObserver* observer; while ((observer = it.GetNext()) != NULL) @@ -3066,6 +3071,9 @@ } void RenderViewImpl::OnSetFocus(bool enable) { + // This message must always be received when the main frame is a + // WebLocalFrame. + CHECK(webview()->mainFrame()->isWebLocalFrame()); RenderWidget::OnSetFocus(enable); #if defined(ENABLE_PLUGINS)
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc index 1d4293da..2a9ad59d 100644 --- a/content/renderer/render_widget.cc +++ b/content/renderer/render_widget.cc
@@ -1045,8 +1045,7 @@ } void RenderWidget::OnHandleInputEvent(const blink::WebInputEvent* input_event, - const ui::LatencyInfo& latency_info, - bool is_keyboard_shortcut) { + const ui::LatencyInfo& latency_info) { if (!input_event) return; base::AutoReset<bool> handling_input_event_resetter(&handling_input_event_, @@ -1158,6 +1157,9 @@ // If this RawKeyDown event corresponds to a browser keyboard shortcut and // it's not processed by webkit, then we need to suppress the upcoming Char // events. + bool is_keyboard_shortcut = + input_event->type == WebInputEvent::RawKeyDown && + static_cast<const WebKeyboardEvent*>(input_event)->isBrowserShortcut; if (!processed && is_keyboard_shortcut) suppress_next_char_events_ = true;
diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h index 608e904..eac8544 100644 --- a/content/renderer/render_widget.h +++ b/content/renderer/render_widget.h
@@ -410,8 +410,7 @@ // RenderWidget IPC message handlers void OnHandleInputEvent(const blink::WebInputEvent* event, - const ui::LatencyInfo& latency_info, - bool keyboard_shortcut); + const ui::LatencyInfo& latency_info); void OnCursorVisibilityChange(bool is_visible); void OnMouseCaptureLost(); virtual void OnSetFocus(bool enable);
diff --git a/content/renderer/render_widget_unittest.cc b/content/renderer/render_widget_unittest.cc index 9211acac..e4319f5 100644 --- a/content/renderer/render_widget_unittest.cc +++ b/content/renderer/render_widget_unittest.cc
@@ -34,7 +34,7 @@ } void SendInputEvent(const blink::WebInputEvent& event) { - OnHandleInputEvent(&event, ui::LatencyInfo(), false); + OnHandleInputEvent(&event, ui::LatencyInfo()); } void set_always_overscroll(bool overscroll) {
diff --git a/content/shell/BUILD.gn b/content/shell/BUILD.gn index 16c5d7f..c3f9fb81 100644 --- a/content/shell/BUILD.gn +++ b/content/shell/BUILD.gn
@@ -149,8 +149,6 @@ "renderer/layout_test/blink_test_helpers.h", "renderer/layout_test/blink_test_runner.cc", "renderer/layout_test/blink_test_runner.h", - "renderer/layout_test/gc_controller.cc", - "renderer/layout_test/gc_controller.h", "renderer/layout_test/layout_test_content_renderer_client.cc", "renderer/layout_test/layout_test_content_renderer_client.h", "renderer/layout_test/layout_test_render_frame_observer.cc",
diff --git a/content/shell/renderer/layout_test/blink_test_runner.cc b/content/shell/renderer/layout_test/blink_test_runner.cc index 726a220..45f129e 100644 --- a/content/shell/renderer/layout_test/blink_test_runner.cc +++ b/content/shell/renderer/layout_test/blink_test_runner.cc
@@ -45,7 +45,6 @@ #include "content/shell/common/shell_messages.h" #include "content/shell/common/shell_switches.h" #include "content/shell/renderer/layout_test/blink_test_helpers.h" -#include "content/shell/renderer/layout_test/gc_controller.h" #include "content/shell/renderer/layout_test/layout_test_render_process_observer.h" #include "content/shell/renderer/layout_test/leak_detector.h" #include "net/base/filename_util.h" @@ -764,7 +763,6 @@ WebTestingSupport::injectInternalsObject(frame); LayoutTestRenderProcessObserver::GetInstance()->test_interfaces()->BindTo( frame); - GCController::Install(frame); } bool BlinkTestRunner::OnMessageReceived(const IPC::Message& message) {
diff --git a/crypto/ec_private_key.h b/crypto/ec_private_key.h index 87af8389..a3ba49d 100644 --- a/crypto/ec_private_key.h +++ b/crypto/ec_private_key.h
@@ -34,9 +34,6 @@ public: ~ECPrivateKey(); - // Returns whether the system supports elliptic curve cryptography. - static bool IsSupported(); - // Creates a new random instance. Can return NULL if initialization fails. // The created key will use the NIST P-256 curve. // TODO(mattm): Add a curve parameter.
diff --git a/crypto/ec_private_key_nss.cc b/crypto/ec_private_key_nss.cc index 5092010c..5f8a4e6 100644 --- a/crypto/ec_private_key_nss.cc +++ b/crypto/ec_private_key_nss.cc
@@ -15,7 +15,6 @@ #include <pk11pub.h> #include <secmod.h> -#include "base/lazy_instance.h" #include "base/logging.h" #include "base/memory/scoped_ptr.h" #include "crypto/nss_util.h" @@ -25,34 +24,6 @@ namespace { -PK11SlotInfo* GetTempKeySlot() { - return PK11_GetInternalSlot(); -} - -class EllipticCurveSupportChecker { - public: - EllipticCurveSupportChecker() { - // NOTE: we can do this check here only because we use the NSS internal - // slot. If we support other slots in the future, checking whether they - // support ECDSA may block NSS, and the value may also change as devices are - // inserted/removed, so we would need to re-check on every use. - crypto::EnsureNSSInit(); - crypto::ScopedPK11Slot slot(GetTempKeySlot()); - supported_ = PK11_DoesMechanism(slot.get(), CKM_EC_KEY_PAIR_GEN) && - PK11_DoesMechanism(slot.get(), CKM_ECDSA); - } - - bool Supported() { - return supported_; - } - - private: - bool supported_; -}; - -static base::LazyInstance<EllipticCurveSupportChecker>::Leaky - g_elliptic_curve_supported = LAZY_INSTANCE_INITIALIZER; - // Copied from rsa_private_key_nss.cc. static bool ReadAttribute(SECKEYPrivateKey* key, CK_ATTRIBUTE_TYPE type, @@ -82,15 +53,10 @@ } // static -bool ECPrivateKey::IsSupported() { - return g_elliptic_curve_supported.Get().Supported(); -} - -// static ECPrivateKey* ECPrivateKey::Create() { EnsureNSSInit(); - ScopedPK11Slot slot(GetTempKeySlot()); + ScopedPK11Slot slot(PK11_GetInternalSlot()); if (!slot) return nullptr; @@ -140,7 +106,7 @@ const std::vector<uint8>& subject_public_key_info) { EnsureNSSInit(); - ScopedPK11Slot slot(GetTempKeySlot()); + ScopedPK11Slot slot(PK11_GetInternalSlot()); if (!slot) return nullptr;
diff --git a/crypto/ec_private_key_openssl.cc b/crypto/ec_private_key_openssl.cc index 1a06028..9836fa6 100644 --- a/crypto/ec_private_key_openssl.cc +++ b/crypto/ec_private_key_openssl.cc
@@ -93,9 +93,6 @@ } // static -bool ECPrivateKey::IsSupported() { return true; } - -// static ECPrivateKey* ECPrivateKey::Create() { OpenSSLErrStackTracer err_tracer(FROM_HERE);
diff --git a/device/BUILD.gn b/device/BUILD.gn index 6c8277a..32adecc 100644 --- a/device/BUILD.gn +++ b/device/BUILD.gn
@@ -41,6 +41,7 @@ "bluetooth/bluetooth_device_win_unittest.cc", "bluetooth/bluetooth_discovery_filter_unittest.cc", "bluetooth/bluetooth_gatt_chromeos_unittest.cc", + "bluetooth/bluetooth_gatt_service_unittest.cc", "bluetooth/bluetooth_low_energy_win_unittest.cc", "bluetooth/bluetooth_service_record_win_unittest.cc", "bluetooth/bluetooth_socket_chromeos_unittest.cc",
diff --git a/device/bluetooth/BUILD.gn b/device/bluetooth/BUILD.gn index 2cb34170..a5ea564 100644 --- a/device/bluetooth/BUILD.gn +++ b/device/bluetooth/BUILD.gn
@@ -200,6 +200,7 @@ java_sources_needing_jni = [ "android/java/src/org/chromium/device/bluetooth/ChromeBluetoothAdapter.java", "android/java/src/org/chromium/device/bluetooth/ChromeBluetoothDevice.java", + "android/java/src/org/chromium/device/bluetooth/ChromeBluetoothRemoteGattService.java", "android/java/src/org/chromium/device/bluetooth/Wrappers.java", ]
diff --git a/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothDevice.java b/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothDevice.java index 037cd95..c55fb45 100644 --- a/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothDevice.java +++ b/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothDevice.java
@@ -163,8 +163,12 @@ if (mNativeBluetoothDeviceAndroid != 0) { for (Wrappers.BluetoothGattServiceWrapper service : mBluetoothGatt.getServices()) { - nativeCreateGattRemoteService(mNativeBluetoothDeviceAndroid, - service.getInstanceId(), service); + // Create a device unique service ID. getInstanceId only differs + // between service instances with the same UUID. + String serviceInstanceId = + service.getUuid().toString() + service.getInstanceId(); + nativeCreateGattRemoteService( + mNativeBluetoothDeviceAndroid, serviceInstanceId, service); } } } @@ -183,6 +187,6 @@ // 'Object' type must be used for |bluetoothGattServiceWrapper| because inner class // Wrappers.BluetoothGattServiceWrapper reference is not handled by jni_generator.py JavaToJni. // http://crbug.com/505554 - private native void nativeCreateGattRemoteService( - long nativeBluetoothDeviceAndroid, int instanceId, Object bluetoothGattServiceWrapper); + private native void nativeCreateGattRemoteService(long nativeBluetoothDeviceAndroid, + String instanceId, Object bluetoothGattServiceWrapper); }
diff --git a/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothRemoteGattService.java b/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothRemoteGattService.java new file mode 100644 index 0000000..62c379a --- /dev/null +++ b/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothRemoteGattService.java
@@ -0,0 +1,46 @@ +// 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.device.bluetooth; + +import org.chromium.base.Log; +import org.chromium.base.annotations.CalledByNative; +import org.chromium.base.annotations.JNINamespace; + +/** + * Exposes android.bluetooth.BluetoothGattService as necessary + * for C++ device::BluetoothRemoteGattServiceAndroid. + * + * Lifetime is controlled by + * device::BluetoothRemoteGattServiceAndroid. + */ +@JNINamespace("device") +final class ChromeBluetoothRemoteGattService { + private static final String TAG = "Bluetooth"; + + final Wrappers.BluetoothGattServiceWrapper mService; + + private ChromeBluetoothRemoteGattService(Wrappers.BluetoothGattServiceWrapper serviceWrapper) { + mService = serviceWrapper; + Log.v(TAG, "ChromeBluetoothRemoteGattService created."); + } + + // --------------------------------------------------------------------------------------------- + // BluetoothRemoteGattServiceAndroid methods implemented in java: + + // Implements BluetoothRemoteGattServiceAndroid::Create. + // 'Object' type must be used because inner class Wrappers.BluetoothGattServiceWrapper reference + // is not handled by jni_generator.py JavaToJni. http://crbug.com/505554 + @CalledByNative + private static ChromeBluetoothRemoteGattService create(Object serviceWrapper) { + return new ChromeBluetoothRemoteGattService( + (Wrappers.BluetoothGattServiceWrapper) serviceWrapper); + } + + // Implements BluetoothRemoteGattServiceAndroid::GetUUID. + @CalledByNative + private String getUUID() { + return mService.getUuid().toString(); + } +}
diff --git a/device/bluetooth/android/java/src/org/chromium/device/bluetooth/Wrappers.java b/device/bluetooth/android/java/src/org/chromium/device/bluetooth/Wrappers.java index df54ee8..9f4d35fb 100644 --- a/device/bluetooth/android/java/src/org/chromium/device/bluetooth/Wrappers.java +++ b/device/bluetooth/android/java/src/org/chromium/device/bluetooth/Wrappers.java
@@ -28,6 +28,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.UUID; /** * Wrapper classes around android.bluetooth.* classes that provide an @@ -333,5 +334,9 @@ public int getInstanceId() { return mService.getInstanceId(); } + + public UUID getUuid() { + return mService.getUuid(); + } } }
diff --git a/device/bluetooth/bluetooth.gyp b/device/bluetooth/bluetooth.gyp index c197d942..f99d0176 100644 --- a/device/bluetooth/bluetooth.gyp +++ b/device/bluetooth/bluetooth.gyp
@@ -256,6 +256,7 @@ 'sources': [ 'android/java/src/org/chromium/device/bluetooth/ChromeBluetoothAdapter.java', 'android/java/src/org/chromium/device/bluetooth/ChromeBluetoothDevice.java', + 'android/java/src/org/chromium/device/bluetooth/ChromeBluetoothRemoteGattService.java', 'android/java/src/org/chromium/device/bluetooth/Wrappers.java', ], 'variables': {
diff --git a/device/bluetooth/bluetooth_device_android.cc b/device/bluetooth/bluetooth_device_android.cc index 1066ac4..fccd24fb 100644 --- a/device/bluetooth/bluetooth_device_android.cc +++ b/device/bluetooth/bluetooth_device_android.cc
@@ -226,11 +226,12 @@ void BluetoothDeviceAndroid::CreateGattRemoteService( JNIEnv* env, jobject caller, - int32_t instanceId, + const jstring& instanceId, jobject bluetooth_gatt_service_wrapper // Java Type: // BluetoothGattServiceWrapper ) { - std::string instanceIdString = base::StringPrintf("%d", instanceId); + std::string instanceIdString = + base::android::ConvertJavaStringToUTF8(env, instanceId); if (gatt_services_.contains(instanceIdString)) return;
diff --git a/device/bluetooth/bluetooth_device_android.h b/device/bluetooth/bluetooth_device_android.h index e830e94..bed6780 100644 --- a/device/bluetooth/bluetooth_device_android.h +++ b/device/bluetooth/bluetooth_device_android.h
@@ -99,7 +99,7 @@ void CreateGattRemoteService( JNIEnv* env, jobject caller, - int32_t instanceId, + const jstring& instanceId, jobject bluetooth_gatt_service_wrapper); // Java Type: // BluetoothGattServiceWrapper
diff --git a/device/bluetooth/bluetooth_device_unittest.cc b/device/bluetooth/bluetooth_device_unittest.cc index a89fc88..c6066ca 100644 --- a/device/bluetooth/bluetooth_device_unittest.cc +++ b/device/bluetooth/bluetooth_device_unittest.cc
@@ -436,10 +436,13 @@ SimulateGattConnection(device); EXPECT_EQ(1, gatt_discovery_attempts_); - // TODO(scheib): Add more control over how many services are created and - // their properties. http://crbug.com/541400 - SimulateGattServicesDiscovered(device); - EXPECT_EQ(2u, device->GetGattServices().size()); + std::vector<std::string> services; + services.push_back("00000000-0000-1000-8000-00805f9b34fb"); + // 2 duplicate UUIDs creating 2 instances. + services.push_back("00000001-0000-1000-8000-00805f9b34fb"); + services.push_back("00000001-0000-1000-8000-00805f9b34fb"); + SimulateGattServicesDiscovered(device, services); + EXPECT_EQ(3u, device->GetGattServices().size()); } #endif // defined(OS_ANDROID)
diff --git a/device/bluetooth/bluetooth_gatt_service_unittest.cc b/device/bluetooth/bluetooth_gatt_service_unittest.cc new file mode 100644 index 0000000..91fd214 --- /dev/null +++ b/device/bluetooth/bluetooth_gatt_service_unittest.cc
@@ -0,0 +1,45 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "device/bluetooth/bluetooth_gatt_service.h" + +#include "testing/gtest/include/gtest/gtest.h" + +#if defined(OS_ANDROID) +#include "device/bluetooth/test/bluetooth_test_android.h" +#elif defined(OS_MACOSX) +#include "device/bluetooth/test/bluetooth_test_mac.h" +#endif + +namespace device { + +#if defined(OS_ANDROID) +TEST_F(BluetoothTest, GetUUIDAndGetIdentifier) { + InitWithFakeAdapter(); + StartDiscoverySession(); + BluetoothDevice* device = DiscoverLowEnergyDevice(3); + device->CreateGattConnection(GetGattConnectionCallback(), + GetConnectErrorCallback()); + ResetEventCounts(); + SimulateGattConnection(device); + EXPECT_EQ(1, gatt_discovery_attempts_); + + // Create multiple instances with the same UUID. + BluetoothUUID uuid("00000000-0000-1000-8000-00805f9b34fb"); + std::vector<std::string> services; + services.push_back(uuid.canonical_value()); + services.push_back(uuid.canonical_value()); + SimulateGattServicesDiscovered(device, services); + + // Each has the same UUID. + EXPECT_EQ(uuid, device->GetGattServices()[0]->GetUUID()); + EXPECT_EQ(uuid, device->GetGattServices()[1]->GetUUID()); + + // Instance IDs are unique. + EXPECT_NE(device->GetGattServices()[0]->GetIdentifier(), + device->GetGattServices()[1]->GetIdentifier()); +} +#endif // defined(OS_ANDROID) + +} // namespace device
diff --git a/device/bluetooth/bluetooth_remote_gatt_service_android.cc b/device/bluetooth/bluetooth_remote_gatt_service_android.cc index aa25fec..c9caa3a3 100644 --- a/device/bluetooth/bluetooth_remote_gatt_service_android.cc +++ b/device/bluetooth/bluetooth_remote_gatt_service_android.cc
@@ -4,8 +4,13 @@ #include "device/bluetooth/bluetooth_remote_gatt_service_android.h" +#include "base/android/jni_android.h" +#include "base/android/jni_string.h" #include "device/bluetooth/bluetooth_adapter_android.h" #include "device/bluetooth/bluetooth_device_android.h" +#include "jni/ChromeBluetoothRemoteGattService_jni.h" + +using base::android::AttachCurrentThread; namespace device { @@ -18,16 +23,26 @@ BluetoothRemoteGattServiceAndroid* service = new BluetoothRemoteGattServiceAndroid(adapter, device, instanceId); + service->j_service_.Reset(Java_ChromeBluetoothRemoteGattService_create( + AttachCurrentThread(), bluetooth_remote_gatt_service_wrapper)); + return service; } +// static +bool BluetoothRemoteGattServiceAndroid::RegisterJNI(JNIEnv* env) { + return RegisterNativesImpl( + env); // Generated in ChromeBluetoothRemoteGattService_jni.h +} + std::string BluetoothRemoteGattServiceAndroid::GetIdentifier() const { return instanceId_; } device::BluetoothUUID BluetoothRemoteGattServiceAndroid::GetUUID() const { - NOTIMPLEMENTED(); - return device::BluetoothUUID(); + return device::BluetoothUUID( + ConvertJavaStringToUTF8(Java_ChromeBluetoothRemoteGattService_getUUID( + AttachCurrentThread(), j_service_.obj()))); } bool BluetoothRemoteGattServiceAndroid::IsLocal() const {
diff --git a/device/bluetooth/bluetooth_remote_gatt_service_android.h b/device/bluetooth/bluetooth_remote_gatt_service_android.h index 6e0e702..5bc9e3d 100644 --- a/device/bluetooth/bluetooth_remote_gatt_service_android.h +++ b/device/bluetooth/bluetooth_remote_gatt_service_android.h
@@ -41,6 +41,9 @@ // BluetoothRemoteGattServiceWrapper std::string instanceId); + // Register C++ methods exposed to Java using JNI. + static bool RegisterJNI(JNIEnv* env); + // device::BluetoothGattService overrides. std::string GetIdentifier() const override; device::BluetoothUUID GetUUID() const override; @@ -69,6 +72,9 @@ std::string instanceId); ~BluetoothRemoteGattServiceAndroid() override; + // Java object org.chromium.device.bluetooth.ChromeBluetoothRemoteGattService. + base::android::ScopedJavaGlobalRef<jobject> j_service_; + // The adapter associated with this service. It's ok to store a raw pointer // here since |adapter_| indirectly owns this instance. BluetoothAdapterAndroid* adapter_;
diff --git a/device/bluetooth/test/android/java/src/org/chromium/device/bluetooth/Fakes.java b/device/bluetooth/test/android/java/src/org/chromium/device/bluetooth/Fakes.java index 062c3c8..2499c7b 100644 --- a/device/bluetooth/test/android/java/src/org/chromium/device/bluetooth/Fakes.java +++ b/device/bluetooth/test/android/java/src/org/chromium/device/bluetooth/Fakes.java
@@ -17,7 +17,9 @@ import org.chromium.base.annotations.JNINamespace; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.UUID; /** * Fake implementations of android.bluetooth.* classes for testing. @@ -212,15 +214,20 @@ // Create a call to onServicesDiscovered on the |chrome_device| using parameter // |status|. @CalledByNative("FakeBluetoothDevice") - private static void servicesDiscovered(ChromeBluetoothDevice chromeDevice, int status) { + private static void servicesDiscovered( + ChromeBluetoothDevice chromeDevice, int status, String uuidsSpaceDelimited) { FakeBluetoothDevice fakeDevice = (FakeBluetoothDevice) chromeDevice.mDevice; - // TODO(scheib): Add more control over how many services are created and - // their properties. http://crbug.com/541400 if (status == android.bluetooth.BluetoothGatt.GATT_SUCCESS) { fakeDevice.mGatt.mServices.clear(); - fakeDevice.mGatt.mServices.add(new FakeBluetoothGattService(0)); - fakeDevice.mGatt.mServices.add(new FakeBluetoothGattService(1)); + HashMap<String, Integer> uuidsToInstanceIdMap = new HashMap<String, Integer>(); + for (String uuid : uuidsSpaceDelimited.split(" ")) { + Integer previousId = uuidsToInstanceIdMap.get(uuid); + int instanceId = (previousId == null) ? 0 : previousId + 1; + uuidsToInstanceIdMap.put(uuid, instanceId); + fakeDevice.mGatt.mServices.add( + new FakeBluetoothGattService(UUID.fromString(uuid), instanceId)); + } } fakeDevice.mGattCallback.onServicesDiscovered(status); @@ -297,9 +304,11 @@ */ static class FakeBluetoothGattService extends Wrappers.BluetoothGattServiceWrapper { final int mInstanceId; + final UUID mUuid; - public FakeBluetoothGattService(int instanceId) { + public FakeBluetoothGattService(UUID uuid, int instanceId) { super(null); + mUuid = uuid; mInstanceId = instanceId; } @@ -307,6 +316,11 @@ public int getInstanceId() { return mInstanceId; } + + @Override + public UUID getUuid() { + return mUuid; + } } // ---------------------------------------------------------------------------------------------
diff --git a/device/bluetooth/test/bluetooth_test.h b/device/bluetooth/test/bluetooth_test.h index 43b47f2..11e6b6b 100644 --- a/device/bluetooth/test/bluetooth_test.h +++ b/device/bluetooth/test/bluetooth_test.h
@@ -84,10 +84,12 @@ // Simulates GattConnection disconnecting. virtual void SimulateGattDisconnection(BluetoothDevice* device) {} - // Simulates success of discovering services. Two services are created. - // TODO(scheib): Add more control over how many services are created and - // their properties. http://crbug.com/541400 - virtual void SimulateGattServicesDiscovered(BluetoothDevice* device) {} + // Simulates success of discovering services. |uuids| is used to create a + // service for each UUID string. Multiple UUIDs with the same value produce + // multiple service instances. + virtual void SimulateGattServicesDiscovered( + BluetoothDevice* device, + const std::vector<std::string>& uuids) {} // Simulates failure to discover services. virtual void SimulateGattServicesDiscoveryError(BluetoothDevice* device) {}
diff --git a/device/bluetooth/test/bluetooth_test_android.cc b/device/bluetooth/test/bluetooth_test_android.cc index 01bc12f..48c2ab2 100644 --- a/device/bluetooth/test/bluetooth_test_android.cc +++ b/device/bluetooth/test/bluetooth_test_android.cc
@@ -4,6 +4,10 @@ #include "device/bluetooth/test/bluetooth_test_android.h" +#include <iterator> +#include <sstream> + +#include "base/android/jni_string.h" #include "base/logging.h" #include "device/bluetooth/android/wrappers.h" #include "device/bluetooth/bluetooth_adapter_android.h" @@ -107,13 +111,22 @@ } void BluetoothTestAndroid::SimulateGattServicesDiscovered( - BluetoothDevice* device) { + BluetoothDevice* device, + const std::vector<std::string>& uuids) { BluetoothDeviceAndroid* device_android = static_cast<BluetoothDeviceAndroid*>(device); + JNIEnv* env = base::android::AttachCurrentThread(); + + // Join UUID strings into a single string. + std::ostringstream uuids_space_delimited; + std::copy(uuids.begin(), uuids.end(), + std::ostream_iterator<std::string>(uuids_space_delimited, " ")); Java_FakeBluetoothDevice_servicesDiscovered( - AttachCurrentThread(), device_android->GetJavaObject().obj(), - 0); // android.bluetooth.BluetoothGatt.GATT_SUCCESS + env, device_android->GetJavaObject().obj(), + 0, // android.bluetooth.BluetoothGatt.GATT_SUCCESS + base::android::ConvertUTF8ToJavaString(env, uuids_space_delimited.str()) + .obj()); } void BluetoothTestAndroid::SimulateGattServicesDiscoveryError( @@ -123,7 +136,8 @@ Java_FakeBluetoothDevice_servicesDiscovered( AttachCurrentThread(), device_android->GetJavaObject().obj(), - 0x00000101); // android.bluetooth.BluetoothGatt.GATT_FAILURE + 0x00000101, // android.bluetooth.BluetoothGatt.GATT_FAILURE + nullptr); } void BluetoothTestAndroid::OnFakeBluetoothDeviceConnectGattCalled(
diff --git a/device/bluetooth/test/bluetooth_test_android.h b/device/bluetooth/test/bluetooth_test_android.h index 4db263b..306d81a 100644 --- a/device/bluetooth/test/bluetooth_test_android.h +++ b/device/bluetooth/test/bluetooth_test_android.h
@@ -31,7 +31,9 @@ void SimulateGattConnectionError(BluetoothDevice* device, BluetoothDevice::ConnectErrorCode) override; void SimulateGattDisconnection(BluetoothDevice* device) override; - void SimulateGattServicesDiscovered(BluetoothDevice* device) override; + void SimulateGattServicesDiscovered( + BluetoothDevice* device, + const std::vector<std::string>& uuids) override; void SimulateGattServicesDiscoveryError(BluetoothDevice* device) override; // Records that Java FakeBluetoothDevice connectGatt was called.
diff --git a/device/core/BUILD.gn b/device/core/BUILD.gn index d931807..e85acb6 100644 --- a/device/core/BUILD.gn +++ b/device/core/BUILD.gn
@@ -2,7 +2,9 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -source_set("core") { +component("core") { + output_name = "device_core" + sources = [ "device_client.cc", "device_client.h", @@ -10,6 +12,8 @@ "device_monitor_win.h", ] + defines = [ "DEVICE_CORE_IMPLEMENTATION" ] + public_deps = [ "//base", ]
diff --git a/device/core/core.gyp b/device/core/core.gyp index 034b9e359..d27073d 100644 --- a/device/core/core.gyp +++ b/device/core/core.gyp
@@ -9,10 +9,13 @@ 'targets': [ { 'target_name': 'device_core', - 'type': 'static_library', + 'type': '<(component)', 'include_dirs': [ '../..', ], + 'defines': [ + 'DEVICE_CORE_IMPLEMENTATION', + ], 'sources': [ 'device_client.cc', 'device_client.h', @@ -20,8 +23,8 @@ 'device_monitor_win.h', ], 'dependencies': [ - '<(DEPTH)/third_party/mojo/mojo_public.gyp:mojo_cpp_bindings', - ], + '../../base/base.gyp:base', + ] }, ], }
diff --git a/device/core/device_client.h b/device/core/device_client.h index d63471b..9fdc7f1 100644 --- a/device/core/device_client.h +++ b/device/core/device_client.h
@@ -6,20 +6,17 @@ #define DEVICE_CORE_DEVICE_CLIENT_H_ #include "base/macros.h" +#include "device/core/device_core_export.h" namespace device { class HidService; class UsbService; -namespace usb { -class DeviceManager; -} - // Interface used by consumers of //device APIs to get pointers to the service // singletons appropriate for a given embedding application. For an example see // //chrome/browser/chrome_device_client.h. -class DeviceClient { +class DEVICE_CORE_EXPORT DeviceClient { public: // Construction sets the single instance. DeviceClient();
diff --git a/device/core/device_core_export.h b/device/core/device_core_export.h new file mode 100644 index 0000000..6f1cddb --- /dev/null +++ b/device/core/device_core_export.h
@@ -0,0 +1,28 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef DEVICE_CORE_DEVICE_CORE_EXPORT_H_ +#define DEVICE_CORE_DEVICE_CORE_EXPORT_H_ + +#if defined(COMPONENT_BUILD) && defined(WIN32) + +#if defined(DEVICE_CORE_IMPLEMENTATION) +#define DEVICE_CORE_EXPORT __declspec(dllexport) +#else +#define DEVICE_CORE_EXPORT __declspec(dllimport) +#endif + +#elif defined(COMPONENT_BUILD) && !defined(WIN32) + +#if defined(DEVICE_CORE_IMPLEMENTATION) +#define DEVICE_CORE_EXPORT __attribute__((visibility("default"))) +#else +#define DEVICE_CORE_EXPORT +#endif + +#else +#define DEVICE_CORE_EXPORT +#endif + +#endif // DEVICE_CORE_DEVICE_CORE_EXPORT_H_
diff --git a/device/core/device_monitor_win.h b/device/core/device_monitor_win.h index e8becd7..36600e4 100644 --- a/device/core/device_monitor_win.h +++ b/device/core/device_monitor_win.h
@@ -8,14 +8,15 @@ #include <windows.h> #include "base/observer_list.h" +#include "device/core/device_core_export.h" namespace device { // Use an instance of this class to observe devices being added and removed // from the system, matched by device interface GUID. -class DeviceMonitorWin { +class DEVICE_CORE_EXPORT DeviceMonitorWin { public: - class Observer { + class DEVICE_CORE_EXPORT Observer { public: virtual void OnDeviceAdded(const GUID& class_guid, const std::string& device_path);
diff --git a/device/device_tests.gyp b/device/device_tests.gyp index a645670..3cc4fc0 100644 --- a/device/device_tests.gyp +++ b/device/device_tests.gyp
@@ -47,6 +47,7 @@ 'bluetooth/bluetooth_device_win_unittest.cc', 'bluetooth/bluetooth_discovery_filter_unittest.cc', 'bluetooth/bluetooth_gatt_chromeos_unittest.cc', + 'bluetooth/bluetooth_gatt_service_unittest.cc', 'bluetooth/bluetooth_low_energy_win_unittest.cc', 'bluetooth/bluetooth_service_record_win_unittest.cc', 'bluetooth/bluetooth_socket_chromeos_unittest.cc',
diff --git a/extensions/browser/BUILD.gn b/extensions/browser/BUILD.gn index 9c9424e..3fe0d25 100644 --- a/extensions/browser/BUILD.gn +++ b/extensions/browser/BUILD.gn
@@ -18,6 +18,8 @@ "//components/pref_registry", "//components/sessions", "//components/ui/zoom", + "//components/update_client", + "//components/version_info", "//components/web_cache/browser", "//components/web_modal", "//content/public/browser",
diff --git a/extensions/browser/extension_system.h b/extensions/browser/extension_system.h index c6d2e09..7758051d 100644 --- a/extensions/browser/extension_system.h +++ b/extensions/browser/extension_system.h
@@ -122,6 +122,13 @@ // so it can be retrieved from ExtensionSystem directly. virtual scoped_ptr<ExtensionSet> GetDependentExtensions( const Extension* extension) = 0; + + // Install an updated version of |extension_id| with the version given in + // temp_dir. Ownership of |temp_dir| in the filesystem is transferred and + // implementors of this function are responsible for cleaning it up on + // errors, etc. + virtual void InstallUpdate(const std::string& extension_id, + const base::FilePath& temp_dir) = 0; }; } // namespace extensions
diff --git a/extensions/browser/extensions_browser_client.cc b/extensions/browser/extensions_browser_client.cc index 495ac50..d113f11 100644 --- a/extensions/browser/extensions_browser_client.cc +++ b/extensions/browser/extensions_browser_client.cc
@@ -6,7 +6,9 @@ #include "base/basictypes.h" #include "base/logging.h" +#include "components/update_client/update_client.h" #include "extensions/browser/extension_error.h" +#include "extensions/browser/updater/update_client_config.h" namespace extensions { @@ -16,6 +18,11 @@ } // namespace +scoped_refptr<update_client::UpdateClient> +ExtensionsBrowserClient::CreateUpdateClient(content::BrowserContext* context) { + return scoped_refptr<update_client::UpdateClient>(nullptr); +} + void ExtensionsBrowserClient::ReportError(content::BrowserContext* context, scoped_ptr<ExtensionError> error) { LOG(ERROR) << error->GetDebugString();
diff --git a/extensions/browser/extensions_browser_client.h b/extensions/browser/extensions_browser_client.h index 89763d9d..a5ddd86 100644 --- a/extensions/browser/extensions_browser_client.h +++ b/extensions/browser/extensions_browser_client.h
@@ -8,6 +8,7 @@ #include <string> #include <vector> +#include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "extensions/browser/extension_event_histogram_value.h" #include "extensions/browser/extension_prefs_observer.h" @@ -35,6 +36,10 @@ class URLRequestJob; } +namespace update_client { +class UpdateClient; +} + namespace extensions { class ApiActivityMonitor; @@ -236,6 +241,10 @@ virtual void AttachExtensionTaskManagerTag(content::WebContents* web_contents, ViewType view_type) {} + // Returns a new UpdateClient. + virtual scoped_refptr<update_client::UpdateClient> CreateUpdateClient( + content::BrowserContext* context); + // Returns the single instance of |this|. static ExtensionsBrowserClient* Get();
diff --git a/extensions/browser/mock_extension_system.cc b/extensions/browser/mock_extension_system.cc index 00e3fc22..efcc546 100644 --- a/extensions/browser/mock_extension_system.cc +++ b/extensions/browser/mock_extension_system.cc
@@ -71,4 +71,9 @@ return scoped_ptr<ExtensionSet>(); } +void MockExtensionSystem::InstallUpdate(const std::string& extension_id, + const base::FilePath& temp_dir) { + NOTREACHED(); +} + } // namespace extensions
diff --git a/extensions/browser/mock_extension_system.h b/extensions/browser/mock_extension_system.h index af847f5..b055b42 100644 --- a/extensions/browser/mock_extension_system.h +++ b/extensions/browser/mock_extension_system.h
@@ -41,6 +41,8 @@ ContentVerifier* content_verifier() override; scoped_ptr<ExtensionSet> GetDependentExtensions( const Extension* extension) override; + void InstallUpdate(const std::string& extension_id, + const base::FilePath& temp_dir) override; private: content::BrowserContext* browser_context_;
diff --git a/extensions/browser/test_extensions_browser_client.cc b/extensions/browser/test_extensions_browser_client.cc index d98f7af..da5ef277c 100644 --- a/extensions/browser/test_extensions_browser_client.cc +++ b/extensions/browser/test_extensions_browser_client.cc
@@ -27,6 +27,11 @@ TestExtensionsBrowserClient::~TestExtensionsBrowserClient() {} +void TestExtensionsBrowserClient::SetUpdateClientFactory( + const base::Callback<update_client::UpdateClient*(void)>& factory) { + update_client_factory_ = factory; +} + void TestExtensionsBrowserClient::SetIncognitoContext(BrowserContext* context) { // If a context is provided it must be off-the-record. DCHECK(!context || context->IsOffTheRecord()); @@ -204,4 +209,12 @@ return nullptr; } +scoped_refptr<update_client::UpdateClient> +TestExtensionsBrowserClient::CreateUpdateClient( + content::BrowserContext* context) { + return update_client_factory_.is_null() + ? nullptr + : make_scoped_refptr(update_client_factory_.Run()); +} + } // namespace extensions
diff --git a/extensions/browser/test_extensions_browser_client.h b/extensions/browser/test_extensions_browser_client.h index 274a8a9..be660e7 100644 --- a/extensions/browser/test_extensions_browser_client.h +++ b/extensions/browser/test_extensions_browser_client.h
@@ -5,7 +5,13 @@ #ifndef EXTENSIONS_BROWSER_TEST_EXTENSIONS_BROWSER_CLIENT_H_ #define EXTENSIONS_BROWSER_TEST_EXTENSIONS_BROWSER_CLIENT_H_ +#include <string> +#include <vector> + +#include "base/callback.h" #include "base/compiler_specific.h" +#include "base/memory/ref_counted.h" +#include "components/update_client/update_client.h" #include "extensions/browser/extensions_browser_client.h" #include "extensions/browser/updater/extension_cache.h" @@ -30,6 +36,10 @@ extension_cache_ = extension_cache.Pass(); } + // Sets a factory to respond to calls of the CreateUpdateClient method. + void SetUpdateClientFactory( + const base::Callback<update_client::UpdateClient*(void)>& factory); + // Associates an incognito context with |main_context_|. void SetIncognitoContext(content::BrowserContext* incognito_context); @@ -97,6 +107,8 @@ bool IsMinBrowserVersionSupported(const std::string& min_version) override; ExtensionWebContentsObserver* GetExtensionWebContentsObserver( content::WebContents* web_contents) override; + scoped_refptr<update_client::UpdateClient> CreateUpdateClient( + content::BrowserContext* context) override; private: content::BrowserContext* main_context_; // Not owned. @@ -110,6 +122,8 @@ scoped_ptr<ExtensionCache> extension_cache_; + base::Callback<update_client::UpdateClient*(void)> update_client_factory_; + DISALLOW_COPY_AND_ASSIGN(TestExtensionsBrowserClient); };
diff --git a/extensions/browser/updater/update_client_config.cc b/extensions/browser/updater/update_client_config.cc new file mode 100644 index 0000000..9f1d0d1 --- /dev/null +++ b/extensions/browser/updater/update_client_config.cc
@@ -0,0 +1,29 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "extensions/browser/updater/update_client_config.h" + +#include "content/public/browser/browser_thread.h" + +namespace extensions { + +UpdateClientConfig::UpdateClientConfig() {} + +scoped_refptr<base::SequencedTaskRunner> +UpdateClientConfig::GetSequencedTaskRunner() const { + return content::BrowserThread::GetBlockingPool() + ->GetSequencedTaskRunnerWithShutdownBehavior( + content::BrowserThread::GetBlockingPool()->GetSequenceToken(), + base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); +} + +scoped_refptr<base::SingleThreadTaskRunner> +UpdateClientConfig::GetSingleThreadTaskRunner() const { + return content::BrowserThread::GetMessageLoopProxyForThread( + content::BrowserThread::FILE); +} + +UpdateClientConfig::~UpdateClientConfig() {} + +} // namespace extensions
diff --git a/extensions/browser/updater/update_client_config.h b/extensions/browser/updater/update_client_config.h new file mode 100644 index 0000000..32e7811f --- /dev/null +++ b/extensions/browser/updater/update_client_config.h
@@ -0,0 +1,40 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EXTENSIONS_BROWSER_UPDATER_UPDATE_CLIENT_CONFIG_H_ +#define EXTENSIONS_BROWSER_UPDATER_UPDATE_CLIENT_CONFIG_H_ + +#include <string> + +#include "base/memory/ref_counted.h" +#include "components/update_client/configurator.h" + +namespace base { +class SequencedTaskRunner; +class SingleThreadTaskRunner; +} + +namespace extensions { + +// Used to provide configuration settings to the UpdateClient. +class UpdateClientConfig : public update_client::Configurator { + public: + UpdateClientConfig(); + + scoped_refptr<base::SequencedTaskRunner> GetSequencedTaskRunner() + const override; + scoped_refptr<base::SingleThreadTaskRunner> GetSingleThreadTaskRunner() + const override; + + protected: + friend class base::RefCountedThreadSafe<UpdateClientConfig>; + ~UpdateClientConfig() override; + + private: + DISALLOW_COPY_AND_ASSIGN(UpdateClientConfig); +}; + +} // namespace extensions + +#endif // EXTENSIONS_BROWSER_UPDATER_UPDATE_CLIENT_CONFIG_H_
diff --git a/extensions/browser/updater/update_data_provider.cc b/extensions/browser/updater/update_data_provider.cc new file mode 100644 index 0000000..e0ad403d --- /dev/null +++ b/extensions/browser/updater/update_data_provider.cc
@@ -0,0 +1,72 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "extensions/browser/updater/update_data_provider.h" + +#include "base/base64.h" +#include "base/bind.h" +#include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "base/stl_util.h" +#include "base/strings/string_util.h" +#include "components/update_client/update_client.h" +#include "content/public/browser/browser_thread.h" +#include "crypto/sha2.h" +#include "extensions/browser/content_verifier.h" +#include "extensions/browser/extension_registry.h" +#include "extensions/browser/extension_system.h" +#include "extensions/browser/updater/update_install_shim.h" +#include "extensions/common/extension.h" + +namespace extensions { + +UpdateDataProvider::UpdateDataProvider(content::BrowserContext* context, + const InstallCallback& callback) + : context_(context), callback_(callback) {} + +UpdateDataProvider::~UpdateDataProvider() {} + +void UpdateDataProvider::Shutdown() { + context_ = nullptr; +} + +void UpdateDataProvider::GetData( + const std::vector<std::string>& ids, + std::vector<update_client::CrxComponent>* data) { + if (!context_) + return; + const ExtensionRegistry* registry = ExtensionRegistry::Get(context_); + for (const auto& id : ids) { + const Extension* extension = registry->GetInstalledExtension(id); + if (!extension) + continue; + data->push_back(update_client::CrxComponent()); + update_client::CrxComponent* info = &data->back(); + std::string pubkey_bytes; + base::Base64Decode(extension->public_key(), &pubkey_bytes); + info->pk_hash.resize(crypto::kSHA256Length, 0); + crypto::SHA256HashString(pubkey_bytes, vector_as_array(&info->pk_hash), + info->pk_hash.size()); + info->version = *extension->version(); + info->allow_background_download = false; + + info->installer = new UpdateInstallShim( + id, extension->path(), + base::Bind(&UpdateDataProvider::RunInstallCallback, this)); + } +} + +void UpdateDataProvider::RunInstallCallback(const std::string& extension_id, + const base::FilePath& temp_dir) { + if (!context_) { + content::BrowserThread::PostBlockingPoolTask( + FROM_HERE, + base::Bind(base::IgnoreResult(&base::DeleteFile), temp_dir, false)); + return; + } else { + callback_.Run(context_, extension_id, temp_dir); + } +} + +} // namespace extensions
diff --git a/extensions/browser/updater/update_data_provider.h b/extensions/browser/updater/update_data_provider.h new file mode 100644 index 0000000..95cea59 --- /dev/null +++ b/extensions/browser/updater/update_data_provider.h
@@ -0,0 +1,69 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EXTENSIONS_BROWSER_UPDATER_UPDATE_DATA_PROVIDER_H_ +#define EXTENSIONS_BROWSER_UPDATER_UPDATE_DATA_PROVIDER_H_ + +#include <string> +#include <vector> + +#include "base/callback.h" +#include "base/macros.h" +#include "base/memory/ref_counted.h" + +namespace base { +class FilePath; +} + +namespace content { +class BrowserContext; +} + +namespace update_client { +struct CrxComponent; +} + +namespace extensions { + +// This class exists to let an UpdateClient retrieve information about a set of +// extensions it is doing an update check for. +class UpdateDataProvider : public base::RefCounted<UpdateDataProvider> { + public: + typedef base::Callback<void(content::BrowserContext* context, + const std::string& /* extension_id */, + const base::FilePath& /* temp_dir */)> + InstallCallback; + + // We need a browser context to use when retrieving data for a set of + // extension ids, as well as a callback for proceeding with installation + // steps once the UpdateClient has downloaded and unpacked an update for an + // extension. + UpdateDataProvider(content::BrowserContext* context, + const InstallCallback& callback); + + // Notify this object that the associated browser context is being shut down + // the pointer to the context should be dropped and no more work should be + // done. + void Shutdown(); + + // Matches update_client::UpdateClient::CrxDataCallback + void GetData(const std::vector<std::string>& ids, + std::vector<update_client::CrxComponent>* data); + + private: + friend class base::RefCounted<UpdateDataProvider>; + ~UpdateDataProvider(); + + void RunInstallCallback(const std::string& extension_id, + const base::FilePath& temp_dir); + + content::BrowserContext* context_; + InstallCallback callback_; + + DISALLOW_COPY_AND_ASSIGN(UpdateDataProvider); +}; + +} // namespace extensions + +#endif // EXTENSIONS_BROWSER_UPDATER_UPDATE_DATA_PROVIDER_H_
diff --git a/extensions/browser/updater/update_install_shim.cc b/extensions/browser/updater/update_install_shim.cc new file mode 100644 index 0000000..4b6f5829 --- /dev/null +++ b/extensions/browser/updater/update_install_shim.cc
@@ -0,0 +1,83 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "extensions/browser/updater/update_install_shim.h" + +#include "base/files/file_enumerator.h" +#include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "base/files/scoped_temp_dir.h" +#include "base/logging.h" +#include "base/strings/string_number_conversions.h" +#include "base/values.h" +#include "content/public/browser/browser_thread.h" + +namespace extensions { + +UpdateInstallShim::UpdateInstallShim(std::string extension_id, + const base::FilePath& extension_root, + const UpdateInstallShimCallback& callback) + : extension_id_(extension_id), + extension_root_(extension_root), + callback_(callback) {} + +void UpdateInstallShim::OnUpdateError(int error) { + VLOG(1) << "OnUpdateError (" << extension_id_ << ") " << error; +} + +bool UpdateInstallShim::Install(const base::DictionaryValue& manifest, + const base::FilePath& unpack_path) { + base::ScopedTempDir temp_dir; + if (!temp_dir.CreateUniqueTempDir()) + return false; + + // The UpdateClient code will delete unpack_path if it still exists after + // this method is done, so we rename it on top of our temp dir. + if (!base::DeleteFile(temp_dir.path(), true) || + !base::Move(unpack_path, temp_dir.path())) { + LOG(ERROR) << "Trying to install update for " << extension_id_ + << "and failed to move " << unpack_path.value() << " to " + << temp_dir.path().value(); + return false; + } + content::BrowserThread::PostTask( + content::BrowserThread::UI, FROM_HERE, + base::Bind(&UpdateInstallShim::RunCallbackOnUIThread, this, + temp_dir.Take())); + return true; +} + +bool UpdateInstallShim::GetInstalledFile(const std::string& file, + base::FilePath* installed_file) { + base::FilePath relative_path = base::FilePath::FromUTF8Unsafe(file); + if (relative_path.IsAbsolute() || relative_path.ReferencesParent()) + return false; + *installed_file = extension_root_.Append(relative_path); + if (!extension_root_.IsParent(*installed_file) || + !base::PathExists(*installed_file)) { + VLOG(1) << "GetInstalledFile failed to find " << installed_file->value(); + installed_file->clear(); + return false; + } + return true; +} + +bool UpdateInstallShim::Uninstall() { + NOTREACHED(); + return false; +} + +UpdateInstallShim::~UpdateInstallShim() {} + +void UpdateInstallShim::RunCallbackOnUIThread(const base::FilePath& temp_dir) { + if (callback_.is_null()) { + content::BrowserThread::PostBlockingPoolTask( + FROM_HERE, base::Bind(base::IgnoreResult(&base::DeleteFile), temp_dir, + true /*recursive */)); + return; + } + callback_.Run(extension_id_, temp_dir); +} + +} // namespace extensions
diff --git a/extensions/browser/updater/update_install_shim.h b/extensions/browser/updater/update_install_shim.h new file mode 100644 index 0000000..586e94e --- /dev/null +++ b/extensions/browser/updater/update_install_shim.h
@@ -0,0 +1,76 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EXTENSIONS_BROWSER_UPDATER_UPDATE_INSTALL_SHIM_H_ +#define EXTENSIONS_BROWSER_UPDATER_UPDATE_INSTALL_SHIM_H_ + +#include <string> + +#include "base/callback.h" +#include "base/files/file_path.h" +#include "components/update_client/update_client.h" + +namespace base { +class DictionaryValue; +} + +namespace extensions { + +// A callback to implement the install of a new version of the extension. +// Takes ownership of the directory at |temp_dir|. +using UpdateInstallShimCallback = + base::Callback<void(const std::string& extension_id, + const base::FilePath& temp_dir)>; + +// This class is used as a shim between the components::update_client and +// extensions code, to help the generic update_client code prepare and then +// install an updated version of an extension. Because the update_client code +// doesn't have the notion of extension ids, we use instances of this class to +// map an install request back to the original update check for a given +// extension. +class UpdateInstallShim : public update_client::CrxInstaller { + public: + // This method takes the id and root directory for an extension we're doing + // an update check for, as well as a callback to call if we get a new version + // of it to install. + UpdateInstallShim(std::string extension_id, + const base::FilePath& extension_root, + const UpdateInstallShimCallback& callback); + + // Called when an update attempt failed. + void OnUpdateError(int error) override; + + // This is called when a new version of an extension is unpacked at + // |unpack_path| and is ready for install. + bool Install(const base::DictionaryValue& manifest, + const base::FilePath& unpack_path) override; + + // This is called by the generic differential update code in the + // update_client to provide the path to an existing file in the current + // version of the extension, so that it can be copied (or serve as the input + // to diff-patching) with output going to the directory with the new version + // being staged on disk for install. + bool GetInstalledFile(const std::string& file, + base::FilePath* installed_file) override; + + // This method is not relevant to extension updating. + bool Uninstall() override; + + private: + friend class base::RefCountedThreadSafe<UpdateInstallShim>; + ~UpdateInstallShim() override; + + // Takes ownership of the directory at path |temp_dir|. + void RunCallbackOnUIThread(const base::FilePath& temp_dir); + + std::string extension_id_; + base::FilePath extension_root_; + UpdateInstallShimCallback callback_; + + DISALLOW_COPY_AND_ASSIGN(UpdateInstallShim); +}; + +} // namespace extensions + +#endif // EXTENSIONS_BROWSER_UPDATER_UPDATE_INSTALL_SHIM_H_
diff --git a/extensions/browser/updater/update_service.cc b/extensions/browser/updater/update_service.cc index 0cb055cf..ad40abd 100644 --- a/extensions/browser/updater/update_service.cc +++ b/extensions/browser/updater/update_service.cc
@@ -4,16 +4,27 @@ #include "extensions/browser/updater/update_service.h" -#include <set> - -#include "base/message_loop/message_loop.h" -#include "components/update_client/update_query_params.h" +#include "base/bind.h" +#include "base/files/file_util.h" +#include "components/update_client/update_client.h" #include "content/public/browser/browser_context.h" -#include "extensions/browser/updater/extension_downloader.h" +#include "extensions/browser/extension_system.h" +#include "extensions/browser/extensions_browser_client.h" +#include "extensions/browser/updater/update_data_provider.h" #include "extensions/browser/updater/update_service_factory.h" -#include "extensions/common/extension_urls.h" -using update_client::UpdateQueryParams; +namespace { + +void UpdateCheckCompleteCallback(int error) {} + +void InstallUpdateCallback(content::BrowserContext* context, + const std::string& extension_id, + const base::FilePath& temp_dir) { + extensions::ExtensionSystem::Get(context) + ->InstallUpdate(extension_id, temp_dir); +} + +} // namespace namespace extensions { @@ -22,61 +33,32 @@ return UpdateServiceFactory::GetForBrowserContext(context); } -void UpdateService::DownloadAndInstall( - const std::string& id, - const base::Callback<void(bool)>& callback) { - DCHECK(download_callback_.is_null()); - download_callback_ = callback; - downloader_->AddPendingExtension(id, extension_urls::GetWebstoreUpdateUrl(), - 0); - downloader_->StartAllPending(nullptr); +void UpdateService::Shutdown() { + if (update_data_provider_) { + update_data_provider_->Shutdown(); + update_data_provider_ = nullptr; + } + update_client_ = nullptr; + context_ = nullptr; } -UpdateService::UpdateService(content::BrowserContext* context) - : browser_context_(context), - downloader_(new ExtensionDownloader(this, context->GetRequestContext())) { - downloader_->set_manifest_query_params( - UpdateQueryParams::Get(UpdateQueryParams::CRX)); +void UpdateService::StartUpdateCheck(std::vector<std::string> extension_ids) { + if (!update_client_) + return; + update_client_->Update(extension_ids, base::Bind(&UpdateDataProvider::GetData, + update_data_provider_), + base::Bind(&UpdateCheckCompleteCallback)); } -UpdateService::~UpdateService() { +UpdateService::UpdateService( + content::BrowserContext* context, + scoped_refptr<update_client::UpdateClient> update_client) + : context_(context), update_client_(update_client) { + CHECK(update_client_); + update_data_provider_ = + new UpdateDataProvider(context_, base::Bind(&InstallUpdateCallback)); } -void UpdateService::OnExtensionDownloadFailed( - const std::string& id, - Error error, - const PingResult& ping, - const std::set<int>& request_ids) { - auto callback = download_callback_; - download_callback_.Reset(); - callback.Run(false); -} - -void UpdateService::OnExtensionDownloadFinished( - const CRXFileInfo& file, - bool file_ownership_passed, - const GURL& download_url, - const std::string& version, - const PingResult& ping, - const std::set<int>& request_id, - const InstallCallback& install_callback) { - // TODO(rockot): Actually unpack and install the CRX. - auto callback = download_callback_; - download_callback_.Reset(); - callback.Run(true); - if (!install_callback.is_null()) - install_callback.Run(true); -} - -bool UpdateService::IsExtensionPending(const std::string& id) { - // TODO(rockot): Implement this. For now all IDs are "pending". - return true; -} - -bool UpdateService::GetExtensionExistingVersion(const std::string& id, - std::string* version) { - // TODO(rockot): Implement this. - return false; -} +UpdateService::~UpdateService() {} } // namespace extensions
diff --git a/extensions/browser/updater/update_service.h b/extensions/browser/updater/update_service.h index 4d19204..0ee321c 100644 --- a/extensions/browser/updater/update_service.h +++ b/extensions/browser/updater/update_service.h
@@ -6,62 +6,53 @@ #define EXTENSIONS_BROWSER_UPDATER_UPDATE_SERVICE_H_ #include <string> +#include <vector> #include "base/callback.h" #include "base/macros.h" #include "base/memory/scoped_ptr.h" #include "components/keyed_service/core/keyed_service.h" -#include "extensions/browser/updater/extension_downloader_delegate.h" namespace content { class BrowserContext; } +namespace update_client { +class UpdateClient; +} + namespace extensions { -class ExtensionDownloader; +class UpdateDataProvider; +class UpdateService; class UpdateServiceFactory; -class UpdateServiceTest; -// This service manages the download, update, and installation of extensions. -// It is currently only used by app_shell, but should eventually replace -// ExtensionUpdater in Chrome. +// This service manages the autoupdate of extensions. It should eventually +// replace ExtensionUpdater in Chrome. // TODO(rockot): Replace ExtensionUpdater with this service. -class UpdateService : public KeyedService, public ExtensionDownloaderDelegate { +class UpdateService : public KeyedService { public: static UpdateService* Get(content::BrowserContext* context); - // TODO(rockot): Remove this. It's a placeholder for a real service interface. - // Downloads and (TODO) installs a CRX within the current browser context. - void DownloadAndInstall(const std::string& id, - const base::Callback<void(bool)>& callback); + void Shutdown() override; + + // Starts an update check for each of |extension_ids|. If there are any + // updates available, they will be downloaded, checked for integrity, + // unpacked, and then passed off to the ExtensionSystem::InstallUpdate method + // for install completion. + void StartUpdateCheck(std::vector<std::string> extension_ids); private: friend class UpdateServiceFactory; - friend class UpdateServiceTest; - explicit UpdateService(content::BrowserContext* context); + UpdateService(content::BrowserContext* context, + scoped_refptr<update_client::UpdateClient> update_client); ~UpdateService() override; - // ExtensionDownloaderDelegate: - void OnExtensionDownloadFailed(const std::string& id, - Error error, - const PingResult& ping, - const std::set<int>& request_ids) override; - void OnExtensionDownloadFinished(const CRXFileInfo& file, - bool file_ownership_passed, - const GURL& download_url, - const std::string& version, - const PingResult& ping, - const std::set<int>& request_id, - const InstallCallback& callback) override; - bool IsExtensionPending(const std::string& id) override; - bool GetExtensionExistingVersion(const std::string& id, - std::string* version) override; + content::BrowserContext* context_; - content::BrowserContext* browser_context_; - scoped_ptr<ExtensionDownloader> downloader_; - base::Callback<void(bool)> download_callback_; + scoped_refptr<update_client::UpdateClient> update_client_; + scoped_refptr<UpdateDataProvider> update_data_provider_; DISALLOW_COPY_AND_ASSIGN(UpdateService); };
diff --git a/extensions/browser/updater/update_service_browsertest.cc b/extensions/browser/updater/update_service_browsertest.cc deleted file mode 100644 index 097de35..0000000 --- a/extensions/browser/updater/update_service_browsertest.cc +++ /dev/null
@@ -1,218 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <map> -#include <string> -#include <utility> - -#include "base/bind.h" -#include "base/files/scoped_temp_dir.h" -#include "base/run_loop.h" -#include "base/strings/stringprintf.h" -#include "content/public/test/test_browser_thread_bundle.h" -#include "content/public/test/test_utils.h" -#include "extensions/browser/api/extensions_api_client.h" -#include "extensions/browser/extensions_browser_client.h" -#include "extensions/browser/updater/update_service.h" -#include "extensions/common/extension_urls.h" -#include "extensions/shell/test/shell_test.h" -#include "net/base/escape.h" -#include "net/http/http_status_code.h" -#include "net/url_request/test_url_fetcher_factory.h" - -namespace extensions { - -namespace { - -using FakeResponse = std::pair<std::string, net::HttpStatusCode>; - -// TODO(rockot): In general there's enough mock-Omaha-noise that this might be -// better placed into some test library code in //components/update_client. -FakeResponse CreateFakeUpdateResponse(const std::string& id, - size_t crx_length) { - std::string response_text = base::StringPrintf( - "<gupdate xmlns=\"http://www.google.com/update2/response\" " - " protocol=\"2.0\" server=\"prod\">\n" - " <daystart elapsed_days=\"2860\" elapsed_seconds=\"42042\"/>\n" - " <app appid=\"%s\" status=\"ok\">\n" - " <updatecheck codebase=\"%s\" fp=\"0\" hash=\"\" hash_sha256=\"\" " - " size=\"%d\" status=\"ok\" version=\"1\"/>\n" - " </app>\n" - "</gupdate>\n", - id.c_str(), - base::StringPrintf("https://fake-omaha-hostname/%s.crx", - id.c_str()).c_str(), - static_cast<int>(crx_length)); - return std::make_pair(response_text, net::HTTP_OK); -} - -FakeResponse CreateFakeUpdateNotFoundResponse() { - return std::make_pair( - std::string( - "<gupdate xmlns=\"http://www.google.com/update2/response\" " - " protocol=\"2.0\" server=\"prod\">\n" - " <daystart elapsed_days=\"4242\" elapsed_seconds=\"42042\"/>\n" - " <app appid=\"\" status=\"error-invalidAppId\">\n" - "</gupdate>"), - net::HTTP_OK); -} - -bool ExtractKeyValueFromComponent(const std::string& component_str, - const std::string& target_key, - std::string* extracted_value) { - url::Component component(0, static_cast<int>(component_str.length())); - url::Component key, value; - while (url::ExtractQueryKeyValue(component_str.c_str(), &component, &key, - &value)) { - if (target_key == component_str.substr(key.begin, key.len)) { - *extracted_value = component_str.substr(value.begin, value.len); - return true; - } - } - return false; -} - -// This extracts an extension ID from an Omaha update query. Queries have the -// form https://foo/bar/update?x=id%3Dabcdefghijklmnopqrstuvwxyzaaaaaa%26... -// This function extracts the 'x' query parameter (e.g. "id%3Dabcdef...."), -// unescapes its value (to become e.g., "id=abcdef...", and then extracts the -// 'id' value from the result (e.g. "abcdef..."). -bool ExtractIdFromUpdateQuery(const std::string& query_str, std::string* id) { - std::string data_string; - if (!ExtractKeyValueFromComponent(query_str, "x", &data_string)) - return false; - data_string = net::UnescapeURLComponent(data_string, - net::UnescapeRule::URL_SPECIAL_CHARS); - if (!ExtractKeyValueFromComponent(data_string, "id", id)) - return false; - EXPECT_EQ(32u, id->size()); - return true; -} - -void ExpectDownloadSuccess(const base::Closure& continuation, bool success) { - EXPECT_TRUE(success) << "Download failed."; - continuation.Run(); -} - -class FakeUpdateURLFetcherFactory : public net::URLFetcherFactory { - public: - FakeUpdateURLFetcherFactory() { EXPECT_TRUE(dir_.CreateUniqueTempDir()); } - - ~FakeUpdateURLFetcherFactory() override {} - - void RegisterFakeExtension(const std::string& id, - const std::string& contents) { - CHECK_EQ(32u, id.size()); - fake_extensions_.insert(std::make_pair(id, contents)); - } - - // net::URLFetcherFactory: - scoped_ptr<net::URLFetcher> CreateURLFetcher( - int id, - const GURL& url, - net::URLFetcher::RequestType request_type, - net::URLFetcherDelegate* delegate) override { - if (url.spec().find(extension_urls::GetWebstoreUpdateUrl().spec()) == 0) { - // Handle fake Omaha requests. - return CreateUpdateManifestFetcher(url, delegate); - } else if (url.spec().find("https://fake-omaha-hostname") == 0) { - // Handle a fake CRX request. - return CreateCrxFetcher(url, delegate); - } - NOTREACHED(); - return nullptr; - } - - private: - scoped_ptr<net::URLFetcher> CreateUpdateManifestFetcher( - const GURL& url, - net::URLFetcherDelegate* delegate) { - // If we have a fake CRX for the ID, return a fake update blob for it. - // Otherwise return an invalid-ID response. - FakeResponse response; - std::string extension_id; - if (!ExtractIdFromUpdateQuery(url.query(), &extension_id)) { - response = CreateFakeUpdateNotFoundResponse(); - } else { - const auto& iter = fake_extensions_.find(extension_id); - if (iter == fake_extensions_.end()) - response = CreateFakeUpdateNotFoundResponse(); - else - response = CreateFakeUpdateResponse(extension_id, iter->second.size()); - } - return scoped_ptr<net::URLFetcher>( - new net::FakeURLFetcher(url, delegate, response.first, response.second, - net::URLRequestStatus::SUCCESS)); - } - - scoped_ptr<net::URLFetcher> CreateCrxFetcher( - const GURL& url, - net::URLFetcherDelegate* delegate) { - FakeResponse response; - std::string extension_id = url.path().substr(1, 32); - const auto& iter = fake_extensions_.find(extension_id); - if (iter == fake_extensions_.end()) - response = std::make_pair(std::string(), net::HTTP_NOT_FOUND); - else - response = std::make_pair(iter->second, net::HTTP_OK); - net::TestURLFetcher* fetcher = - new net::FakeURLFetcher(url, delegate, response.first, response.second, - net::URLRequestStatus::SUCCESS); - base::FilePath path = dir_.path().Append( - base::FilePath::FromUTF8Unsafe(url.path().substr(1))); - fetcher->SetResponseFilePath(path); - return scoped_ptr<net::URLFetcher>(fetcher); - } - - base::ScopedTempDir dir_; - - std::map<std::string, std::string> fake_extensions_; - - DISALLOW_COPY_AND_ASSIGN(FakeUpdateURLFetcherFactory); -}; - -} // namespace - -class UpdateServiceTest : public AppShellTest { - public: - UpdateServiceTest() {} - ~UpdateServiceTest() override {} - - void SetUpOnMainThread() override { - AppShellTest::SetUpOnMainThread(); - - update_service_ = UpdateService::Get(browser_context()); - - default_url_fetcher_factory_.reset(new FakeUpdateURLFetcherFactory()); - url_fetcher_factory_.reset( - new net::FakeURLFetcherFactory(default_url_fetcher_factory_.get())); - } - - protected: - void RegisterFakeExtension(const std::string& id, - const std::string& crx_contents) { - default_url_fetcher_factory_->RegisterFakeExtension(id, crx_contents); - } - - UpdateService* update_service() const { return update_service_; } - - private: - scoped_ptr<FakeUpdateURLFetcherFactory> default_url_fetcher_factory_; - scoped_ptr<net::FakeURLFetcherFactory> url_fetcher_factory_; - - UpdateService* update_service_; -}; - -IN_PROC_BROWSER_TEST_F(UpdateServiceTest, DownloadAndInstall) { - const char kCrxId[] = "abcdefghijklmnopqrstuvwxyzaaaaaa"; - const char kCrxContents[] = "Hello, world!"; - RegisterFakeExtension(kCrxId, kCrxContents); - - base::RunLoop run_loop; - update_service()->DownloadAndInstall( - kCrxId, base::Bind(ExpectDownloadSuccess, run_loop.QuitClosure())); - run_loop.Run(); -} - -} // namespace extensions
diff --git a/extensions/browser/updater/update_service_factory.cc b/extensions/browser/updater/update_service_factory.cc index a87c88bd..e441dc3 100644 --- a/extensions/browser/updater/update_service_factory.cc +++ b/extensions/browser/updater/update_service_factory.cc
@@ -5,7 +5,9 @@ #include "extensions/browser/updater/update_service_factory.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" +#include "components/update_client/update_client.h" #include "extensions/browser/extension_registry_factory.h" +#include "extensions/browser/extensions_browser_client.h" #include "extensions/browser/process_manager_factory.h" #include "extensions/browser/updater/update_service.h" @@ -27,8 +29,6 @@ : BrowserContextKeyedServiceFactory( "UpdateService", BrowserContextDependencyManager::GetInstance()) { - DependsOn(extensions::ExtensionRegistryFactory::GetInstance()); - DependsOn(extensions::ProcessManagerFactory::GetInstance()); } UpdateServiceFactory::~UpdateServiceFactory() { @@ -36,7 +36,8 @@ KeyedService* UpdateServiceFactory::BuildServiceInstanceFor( content::BrowserContext* context) const { - return new UpdateService(context); + return new UpdateService( + context, ExtensionsBrowserClient::Get()->CreateUpdateClient(context)); } } // namespace extensions
diff --git a/extensions/browser/updater/update_service_unittest.cc b/extensions/browser/updater/update_service_unittest.cc new file mode 100644 index 0000000..f570303 --- /dev/null +++ b/extensions/browser/updater/update_service_unittest.cc
@@ -0,0 +1,248 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <vector> + +#include "base/files/file_util.h" +#include "base/files/scoped_temp_dir.h" +#include "base/run_loop.h" +#include "base/values.h" +#include "components/crx_file/id_util.h" +#include "components/update_client/update_client.h" +#include "content/public/test/test_browser_thread_bundle.h" +#include "content/public/test/test_utils.h" +#include "extensions/browser/extension_registry.h" +#include "extensions/browser/extensions_test.h" +#include "extensions/browser/mock_extension_system.h" +#include "extensions/browser/test_extensions_browser_client.h" +#include "extensions/browser/updater/update_service.h" +#include "extensions/common/extension_builder.h" +#include "extensions/common/value_builder.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +class FakeUpdateClient : public update_client::UpdateClient { + public: + FakeUpdateClient(); + + // Returns the data we've gotten from the CrxDataCallback for ids passed to + // the Update function. + std::vector<update_client::CrxComponent>* data() { return &data_; } + + // update_client::UpdateClient + void AddObserver(Observer* observer) override {} + void RemoveObserver(Observer* observer) override {} + void Install(const std::string& id, + const CrxDataCallback& crx_data_callback, + const CompletionCallback& completion_callback) override {} + void Update(const std::vector<std::string>& ids, + const CrxDataCallback& crx_data_callback, + const CompletionCallback& completion_callback) override; + bool GetCrxUpdateState( + const std::string& id, + update_client::CrxUpdateItem* update_item) const override { + return false; + } + bool IsUpdating(const std::string& id) const override { return false; } + + protected: + friend class base::RefCounted<FakeUpdateClient>; + ~FakeUpdateClient() override {} + + std::vector<update_client::CrxComponent> data_; +}; + +FakeUpdateClient::FakeUpdateClient() {} + +void FakeUpdateClient::Update(const std::vector<std::string>& ids, + const CrxDataCallback& crx_data_callback, + const CompletionCallback& completion_callback) { + crx_data_callback.Run(ids, &data_); +} + +} // namespace + +namespace extensions { + +namespace { + +// A fake ExtensionSystem that lets us intercept calls to install new +// versions of an extension. +class FakeExtensionSystem : public MockExtensionSystem { + public: + explicit FakeExtensionSystem(content::BrowserContext* context) + : MockExtensionSystem(context) {} + ~FakeExtensionSystem() override {} + + struct InstallUpdateRequest { + std::string extension_id; + base::FilePath temp_dir; + }; + + std::vector<InstallUpdateRequest>* install_requests() { + return &install_requests_; + } + + void set_install_callback(const base::Closure& callback) { + next_install_callback_ = callback; + } + + // ExtensionSystem override + void InstallUpdate(const std::string& extension_id, + const base::FilePath& temp_dir) override { + base::DeleteFile(temp_dir, true /*recursive*/); + InstallUpdateRequest request; + request.extension_id = extension_id; + request.temp_dir = temp_dir; + install_requests_.push_back(request); + if (!next_install_callback_.is_null()) { + base::Closure tmp = next_install_callback_; + next_install_callback_.Reset(); + tmp.Run(); + } + } + + private: + std::vector<InstallUpdateRequest> install_requests_; + base::Closure next_install_callback_; +}; + +class UpdateServiceTest : public ExtensionsTest { + public: + UpdateServiceTest() { + extensions_browser_client()->set_extension_system_factory( + &fake_extension_system_factory_); + } + ~UpdateServiceTest() override {} + + void SetUp() override { + ExtensionsTest::SetUp(); + browser_threads_.reset(new content::TestBrowserThreadBundle( + content::TestBrowserThreadBundle::DEFAULT)); + + extensions_browser_client()->SetUpdateClientFactory(base::Bind( + &UpdateServiceTest::CreateUpdateClient, base::Unretained(this))); + + update_service_ = UpdateService::Get(browser_context()); + } + + protected: + UpdateService* update_service() const { return update_service_; } + FakeUpdateClient* update_client() const { return update_client_.get(); } + + update_client::UpdateClient* CreateUpdateClient() { + // We only expect that this will get called once, so consider it an error + // if our update_client_ is already non-null. + EXPECT_EQ(nullptr, update_client_.get()); + update_client_ = new FakeUpdateClient(); + return update_client_.get(); + } + + // Helper function that creates a file at |relative_path| within |directory| + // and fills it with |content|. + bool AddFileToDirectory(const base::FilePath& directory, + const base::FilePath& relative_path, + const std::string& content) { + base::FilePath full_path = directory.Append(relative_path); + if (!CreateDirectory(full_path.DirName())) + return false; + int result = base::WriteFile(full_path, content.data(), content.size()); + return (static_cast<size_t>(result) == content.size()); + } + + FakeExtensionSystem* extension_system() { + return static_cast<FakeExtensionSystem*>( + fake_extension_system_factory_.GetForBrowserContext(browser_context())); + } + + private: + UpdateService* update_service_; + scoped_refptr<FakeUpdateClient> update_client_; + scoped_ptr<content::TestBrowserThreadBundle> browser_threads_; + MockExtensionSystemFactory<FakeExtensionSystem> + fake_extension_system_factory_; +}; + +TEST_F(UpdateServiceTest, BasicUpdateOperations) { + // Create a temporary directory that a fake extension will live in and fill + // it with some test files. + base::ScopedTempDir temp_dir; + ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); + base::FilePath foo_js(FILE_PATH_LITERAL("foo.js")); + base::FilePath bar_html(FILE_PATH_LITERAL("bar/bar.html")); + ASSERT_TRUE(AddFileToDirectory(temp_dir.path(), foo_js, "hello")) + << "Failed to write " << temp_dir.path().value() << "/" << foo_js.value(); + ASSERT_TRUE(AddFileToDirectory(temp_dir.path(), bar_html, "world")); + + ExtensionBuilder builder; + builder.SetManifest(DictionaryBuilder() + .Set("name", "Foo") + .Set("version", "1.0") + .Set("manifest_version", 2)); + builder.SetID(crx_file::id_util::GenerateId("whatever")); + builder.SetPath(temp_dir.path()); + + scoped_refptr<Extension> extension1(builder.Build()); + + ExtensionRegistry::Get(browser_context())->AddEnabled(extension1); + std::vector<std::string> ids; + ids.push_back(extension1->id()); + + // Start an update check and verify that the UpdateClient was sent the right + // data. + update_service()->StartUpdateCheck(ids); + std::vector<update_client::CrxComponent>* data = update_client()->data(); + ASSERT_NE(nullptr, data); + ASSERT_EQ(1u, data->size()); + + ASSERT_TRUE(data->at(0).version.Equals(*extension1->version())); + update_client::CrxInstaller* installer = data->at(0).installer.get(); + ASSERT_NE(installer, nullptr); + + // The GetInstalledFile method is used when processing differential updates + // to get a path to an existing file in an extension. We want to test a + // number of scenarios to be user we handle invalid relative paths, don't + // accidentally return paths outside the extension's dir, etc. + base::FilePath tmp; + EXPECT_TRUE(installer->GetInstalledFile(foo_js.MaybeAsASCII(), &tmp)); + EXPECT_EQ(temp_dir.path().Append(foo_js), tmp) << tmp.value(); + + EXPECT_TRUE(installer->GetInstalledFile(bar_html.MaybeAsASCII(), &tmp)); + EXPECT_EQ(temp_dir.path().Append(bar_html), tmp) << tmp.value(); + + EXPECT_FALSE(installer->GetInstalledFile("does_not_exist", &tmp)); + EXPECT_FALSE(installer->GetInstalledFile("does/not/exist", &tmp)); + EXPECT_FALSE(installer->GetInstalledFile("/does/not/exist", &tmp)); + EXPECT_FALSE(installer->GetInstalledFile("C:\\tmp", &tmp)); + + base::FilePath system_temp_dir; + ASSERT_TRUE(base::GetTempDir(&system_temp_dir)); + EXPECT_FALSE( + installer->GetInstalledFile(system_temp_dir.MaybeAsASCII(), &tmp)); + + // Test the install callback. + base::ScopedTempDir new_version_dir; + ASSERT_TRUE(new_version_dir.CreateUniqueTempDir()); + scoped_ptr<base::DictionaryValue> new_manifest( + extension1->manifest()->value()->DeepCopy()); + new_manifest->SetString("version", "2.0"); + + installer->Install(*new_manifest, new_version_dir.path()); + + scoped_refptr<content::MessageLoopRunner> loop_runner = + new content::MessageLoopRunner(); + extension_system()->set_install_callback(loop_runner->QuitClosure()); + loop_runner->Run(); + + std::vector<FakeExtensionSystem::InstallUpdateRequest>* requests = + extension_system()->install_requests(); + ASSERT_EQ(1u, requests->size()); + EXPECT_EQ(requests->at(0).extension_id, extension1->id()); + EXPECT_NE(requests->at(0).temp_dir.value(), new_version_dir.path().value()); +} + +} // namespace + +} // namespace extensions
diff --git a/extensions/common/BUILD.gn b/extensions/common/BUILD.gn index 3a557d3..c0bff59 100644 --- a/extensions/common/BUILD.gn +++ b/extensions/common/BUILD.gn
@@ -41,10 +41,12 @@ "//build/config/compiler:no_size_t_to_int_warning", ] - deps = [ + public_deps = [ ":common_constants", ":mojo", + ] + deps = [ # TODO(benwells): figure out what to do with the api target and # api resources compiled into the chrome resource bundle. # http://crbug.com/162530
diff --git a/extensions/common/api/BUILD.gn b/extensions/common/api/BUILD.gn index 474e041..b589fd23 100644 --- a/extensions/common/api/BUILD.gn +++ b/extensions/common/api/BUILD.gn
@@ -24,8 +24,8 @@ } # GYP version: extensions/common/api/api.gyp:extensions_api -source_set("api") { - deps = [ +group("api") { + public_deps = [ ":mojom", ":generated_api", ]
diff --git a/extensions/extensions.gyp b/extensions/extensions.gyp index c7976da..3c7657e 100644 --- a/extensions/extensions.gyp +++ b/extensions/extensions.gyp
@@ -111,7 +111,9 @@ '../components/components.gyp:sessions_content', '../components/components.gyp:storage_monitor', '../components/components.gyp:ui_zoom', + '../components/components.gyp:update_client', '../components/components.gyp:variations', + '../components/components.gyp:version_info', '../components/components.gyp:web_cache_browser', '../components/components.gyp:web_modal', '../content/content.gyp:content_browser',
diff --git a/extensions/extensions.gypi b/extensions/extensions.gypi index 450a943..d730681 100644 --- a/extensions/extensions.gypi +++ b/extensions/extensions.gypi
@@ -752,6 +752,12 @@ 'browser/updater/request_queue_impl.h', 'browser/updater/safe_manifest_parser.cc', 'browser/updater/safe_manifest_parser.h', + 'browser/updater/update_client_config.cc', + 'browser/updater/update_client_config.h', + 'browser/updater/update_data_provider.cc', + 'browser/updater/update_data_provider.h', + 'browser/updater/update_install_shim.cc', + 'browser/updater/update_install_shim.h', 'browser/updater/update_service.cc', 'browser/updater/update_service.h', 'browser/updater/update_service_factory.cc',
diff --git a/extensions/extensions_tests.gypi b/extensions/extensions_tests.gypi index 2019e37c..aab6570 100644 --- a/extensions/extensions_tests.gypi +++ b/extensions/extensions_tests.gypi
@@ -27,7 +27,6 @@ 'browser/guest_view/web_view/web_view_apitest.cc', 'browser/guest_view/web_view/web_view_apitest.h', 'browser/guest_view/web_view/web_view_media_access_apitest.cc', - 'browser/updater/update_service_browsertest.cc', 'shell/browser/geolocation/geolocation_apitest.cc', 'shell/browser/shell_browsertest.cc', 'shell/test/shell_apitest.cc', @@ -98,6 +97,7 @@ 'browser/extension_throttle_test_support.cc', 'browser/extension_throttle_test_support.h', 'browser/extension_throttle_unittest.cc', + 'browser/updater/update_service_unittest.cc', 'browser/value_store/leveldb_value_store_unittest.cc', 'browser/value_store/testing_value_store_unittest.cc', 'browser/value_store/value_store_change_unittest.cc',
diff --git a/extensions/shell/browser/shell_browser_main_parts.cc b/extensions/shell/browser/shell_browser_main_parts.cc index 073dacb..01536790 100644 --- a/extensions/shell/browser/shell_browser_main_parts.cc +++ b/extensions/shell/browser/shell_browser_main_parts.cc
@@ -73,13 +73,6 @@ namespace extensions { -namespace { - -void CrxInstallComplete(bool success) { - VLOG(1) << "CRX download complete. Success: " << success; -} -} - ShellBrowserMainParts::ShellBrowserMainParts( const content::MainFunctionParams& parameters, ShellBrowserMainDelegate* browser_main_delegate) @@ -211,17 +204,6 @@ base::Bind(nacl::NaClProcessHost::EarlyStartup)); #endif - // TODO(rockot): Remove this temporary hack test. - std::string install_crx_id = - cmd->GetSwitchValueASCII(switches::kAppShellInstallCrx); - if (install_crx_id.size() != 0) { - CHECK(install_crx_id.size() == 32) - << "Extension ID must be exactly 32 characters long."; - UpdateService* update_service = UpdateService::Get(browser_context_.get()); - update_service->DownloadAndInstall(install_crx_id, - base::Bind(CrxInstallComplete)); - } - devtools_http_handler_.reset( content::ShellDevToolsManagerDelegate::CreateHttpHandler( browser_context_.get()));
diff --git a/extensions/shell/browser/shell_extension_system.cc b/extensions/shell/browser/shell_extension_system.cc index 0457491..b6cff6a 100644 --- a/extensions/shell/browser/shell_extension_system.cc +++ b/extensions/shell/browser/shell_extension_system.cc
@@ -176,6 +176,12 @@ return make_scoped_ptr(new ExtensionSet()); } +void ShellExtensionSystem::InstallUpdate(const std::string& extension_id, + const base::FilePath& temp_dir) { + NOTREACHED(); + base::DeleteFile(temp_dir, true /* recursive */); +} + void ShellExtensionSystem::OnExtensionRegisteredWithRequestContexts( scoped_refptr<Extension> extension) { ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context_);
diff --git a/extensions/shell/browser/shell_extension_system.h b/extensions/shell/browser/shell_extension_system.h index f042f2d7..ca2cb5e 100644 --- a/extensions/shell/browser/shell_extension_system.h +++ b/extensions/shell/browser/shell_extension_system.h
@@ -64,6 +64,8 @@ ContentVerifier* content_verifier() override; scoped_ptr<ExtensionSet> GetDependentExtensions( const Extension* extension) override; + void InstallUpdate(const std::string& extension_id, + const base::FilePath& temp_dir) override; private: void OnExtensionRegisteredWithRequestContexts(
diff --git a/extensions/shell/common/switches.cc b/extensions/shell/common/switches.cc index fbb5783..66bd7e5 100644 --- a/extensions/shell/common/switches.cc +++ b/extensions/shell/common/switches.cc
@@ -13,9 +13,6 @@ // Size for the host window to create (i.e. "800x600"). const char kAppShellHostWindowSize[] = "app-shell-host-window-size"; -// ID of an extension CRX to be downloaded from the web store. -const char kAppShellInstallCrx[] = "app-shell-install-crx"; - // SSID of the preferred WiFi network. const char kAppShellPreferredNetwork[] = "app-shell-preferred-network";
diff --git a/extensions/shell/common/switches.h b/extensions/shell/common/switches.h index b6b3932..7cfe1d6 100644 --- a/extensions/shell/common/switches.h +++ b/extensions/shell/common/switches.h
@@ -12,7 +12,6 @@ // alongside the definition of their values in the .cc file. extern const char kAppShellAllowRoaming[]; extern const char kAppShellHostWindowSize[]; -extern const char kAppShellInstallCrx[]; extern const char kAppShellPreferredNetwork[]; extern const char kAppShellRefreshToken[]; extern const char kAppShellUser[];
diff --git a/ios/chrome/browser/DEPS b/ios/chrome/browser/DEPS index 5a4e50be..0f3d585 100644 --- a/ios/chrome/browser/DEPS +++ b/ios/chrome/browser/DEPS
@@ -69,9 +69,8 @@ "+third_party/google_toolbox_for_mac", "+ui", - # Those don't works on iOS or depends on //content, exclude them. + # Those depend on //content; exclude them. "-components/metrics/gpu", - "-components/metrics/profiler", # For tests. "+ios/chrome/test",
diff --git a/ios/chrome/browser/metrics/ios_chrome_metrics_service_client.cc b/ios/chrome/browser/metrics/ios_chrome_metrics_service_client.cc new file mode 100644 index 0000000..06a35333 --- /dev/null +++ b/ios/chrome/browser/metrics/ios_chrome_metrics_service_client.cc
@@ -0,0 +1,327 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ios/chrome/browser/metrics/ios_chrome_metrics_service_client.h" + +#include <vector> + +#include "base/bind.h" +#include "base/callback.h" +#include "base/command_line.h" +#include "base/files/file_path.h" +#include "base/logging.h" +#include "base/metrics/histogram.h" +#include "base/prefs/pref_registry_simple.h" +#include "base/prefs/pref_service.h" +#include "base/process/process_metrics.h" +#include "base/rand_util.h" +#include "base/strings/string16.h" +#include "base/threading/platform_thread.h" +#include "components/crash/core/common/crash_keys.h" +#include "components/metrics/call_stack_profile_metrics_provider.h" +#include "components/metrics/drive_metrics_provider.h" +#include "components/metrics/metrics_pref_names.h" +#include "components/metrics/metrics_service.h" +#include "components/metrics/net/net_metrics_log_uploader.h" +#include "components/metrics/net/network_metrics_provider.h" +#include "components/metrics/net/version_utils.h" +#include "components/metrics/profiler/profiler_metrics_provider.h" +#include "components/metrics/profiler/tracking_synchronizer.h" +#include "components/metrics/stability_metrics_helper.h" +#include "components/metrics/ui/screen_info_metrics_provider.h" +#include "components/metrics/url_constants.h" +#include "components/omnibox/browser/omnibox_metrics_provider.h" +#include "components/signin/core/browser/signin_status_metrics_provider.h" +#include "components/variations/variations_associated_data.h" +#include "components/version_info/version_info.h" +#include "ios/chrome/browser/application_context.h" +#include "ios/chrome/browser/chrome_paths.h" +#include "ios/chrome/browser/google/google_brand.h" +#include "ios/chrome/browser/metrics/ios_chrome_stability_metrics_provider.h" +#include "ios/chrome/browser/metrics/ios_stability_metrics_provider.h" +#include "ios/chrome/browser/signin/ios_chrome_signin_status_metrics_provider_delegate.h" +#include "ios/chrome/browser/tab_parenting_global_observer.h" +#include "ios/chrome/browser/ui/browser_otr_state.h" +#include "ios/chrome/common/channel_info.h" +#include "ios/web/public/web_thread.h" + +namespace { + +// Standard interval between log uploads, in seconds. +const int kStandardUploadIntervalSeconds = 5 * 60; // Five minutes. +const int kStandardUploadIntervalCellularSeconds = 15 * 60; // Fifteen minutes. + +// Returns true if current connection type is cellular and user is assigned to +// experimental group for enabled cellular uploads. +bool IsCellularLogicEnabled() { + if (variations::GetVariationParamValue("UMA_EnableCellularLogUpload", + "Enabled") != "true" || + variations::GetVariationParamValue("UMA_EnableCellularLogUpload", + "Optimize") == "false") { + return false; + } + + return net::NetworkChangeNotifier::IsConnectionCellular( + net::NetworkChangeNotifier::GetConnectionType()); +} + +} // namespace + +IOSChromeMetricsServiceClient::IOSChromeMetricsServiceClient( + metrics::MetricsStateManager* state_manager) + : metrics_state_manager_(state_manager), + stability_metrics_provider_(nullptr), + profiler_metrics_provider_(nullptr), + drive_metrics_provider_(nullptr), + start_time_(base::TimeTicks::Now()), + has_uploaded_profiler_data_(false), + weak_ptr_factory_(this) { + DCHECK(thread_checker_.CalledOnValidThread()); + RegisterForNotifications(); +} + +IOSChromeMetricsServiceClient::~IOSChromeMetricsServiceClient() { + DCHECK(thread_checker_.CalledOnValidThread()); +} + +// static +scoped_ptr<IOSChromeMetricsServiceClient> IOSChromeMetricsServiceClient::Create( + metrics::MetricsStateManager* state_manager, + PrefService* local_state) { + // Perform two-phase initialization so that |client->metrics_service_| only + // receives pointers to fully constructed objects. + scoped_ptr<IOSChromeMetricsServiceClient> client( + new IOSChromeMetricsServiceClient(state_manager)); + client->Initialize(); + + return client.Pass(); +} + +// static +void IOSChromeMetricsServiceClient::RegisterPrefs( + PrefRegistrySimple* registry) { + metrics::MetricsService::RegisterPrefs(registry); + metrics::StabilityMetricsHelper::RegisterPrefs(registry); +} + +void IOSChromeMetricsServiceClient::SetMetricsClientId( + const std::string& client_id) { + crash_keys::SetMetricsClientIdFromGUID(client_id); +} + +void IOSChromeMetricsServiceClient::OnRecordingDisabled() { + crash_keys::ClearMetricsClientId(); +} + +bool IOSChromeMetricsServiceClient::IsOffTheRecordSessionActive() { + return ::IsOffTheRecordSessionActive(); +} + +int32 IOSChromeMetricsServiceClient::GetProduct() { + return metrics::ChromeUserMetricsExtension::CHROME; +} + +std::string IOSChromeMetricsServiceClient::GetApplicationLocale() { + return GetApplicationContext()->GetApplicationLocale(); +} + +bool IOSChromeMetricsServiceClient::GetBrand(std::string* brand_code) { + return ios::google_brand::GetBrand(brand_code); +} + +metrics::SystemProfileProto::Channel +IOSChromeMetricsServiceClient::GetChannel() { + return metrics::AsProtobufChannel(::GetChannel()); +} + +std::string IOSChromeMetricsServiceClient::GetVersionString() { + return metrics::GetVersionString(); +} + +void IOSChromeMetricsServiceClient::OnLogUploadComplete() {} + +void IOSChromeMetricsServiceClient::InitializeSystemProfileMetrics( + const base::Closure& done_callback) { + finished_init_task_callback_ = done_callback; + drive_metrics_provider_->GetDriveMetrics( + base::Bind(&IOSChromeMetricsServiceClient::OnInitTaskGotDriveMetrics, + weak_ptr_factory_.GetWeakPtr())); +} + +void IOSChromeMetricsServiceClient::CollectFinalMetricsForLog( + const base::Closure& done_callback) { + DCHECK(thread_checker_.CalledOnValidThread()); + + collect_final_metrics_done_callback_ = done_callback; + + if (ShouldIncludeProfilerDataInLog()) { + // Fetch profiler data. This will call into + // |FinishedReceivingProfilerData()| when the task completes. + metrics::TrackingSynchronizer::FetchProfilerDataAsynchronously( + weak_ptr_factory_.GetWeakPtr()); + } else { + CollectFinalHistograms(); + } +} + +scoped_ptr<metrics::MetricsLogUploader> +IOSChromeMetricsServiceClient::CreateUploader( + const base::Callback<void(int)>& on_upload_complete) { + return scoped_ptr<metrics::MetricsLogUploader>( + new metrics::NetMetricsLogUploader( + GetApplicationContext()->GetSystemURLRequestContext(), + metrics::kDefaultMetricsServerUrl, metrics::kDefaultMetricsMimeType, + on_upload_complete)); +} + +base::TimeDelta IOSChromeMetricsServiceClient::GetStandardUploadInterval() { + if (IsCellularLogicEnabled()) + return base::TimeDelta::FromSeconds(kStandardUploadIntervalCellularSeconds); + return base::TimeDelta::FromSeconds(kStandardUploadIntervalSeconds); +} + +base::string16 IOSChromeMetricsServiceClient::GetRegistryBackupKey() { + return base::string16(); +} + +void IOSChromeMetricsServiceClient::WebStateDidStartLoading( + web::WebState* web_state) { + metrics_service_->OnApplicationNotIdle(); +} + +void IOSChromeMetricsServiceClient::WebStateDidStopLoading( + web::WebState* web_state) { + metrics_service_->OnApplicationNotIdle(); +} + +void IOSChromeMetricsServiceClient::LogRendererProcessCrash() { + stability_metrics_provider_->LogRendererCrash(); +} + +void IOSChromeMetricsServiceClient::Initialize() { + metrics_service_.reset(new metrics::MetricsService( + metrics_state_manager_, this, GetApplicationContext()->GetLocalState())); + + // Register metrics providers. + metrics_service_->RegisterMetricsProvider( + scoped_ptr<metrics::MetricsProvider>(new metrics::NetworkMetricsProvider( + web::WebThread::GetBlockingPool()))); + + // Currently, we configure OmniboxMetricsProvider to not log events to UMA + // if there is a single incognito session visible. In the future, it may + // be worth revisiting this to still log events from non-incognito sessions. + metrics_service_->RegisterMetricsProvider( + scoped_ptr<metrics::MetricsProvider>(new OmniboxMetricsProvider( + base::Bind(&::IsOffTheRecordSessionActive)))); + + stability_metrics_provider_ = new IOSChromeStabilityMetricsProvider( + GetApplicationContext()->GetLocalState()); + metrics_service_->RegisterMetricsProvider( + scoped_ptr<metrics::MetricsProvider>(stability_metrics_provider_)); + + metrics_service_->RegisterMetricsProvider( + scoped_ptr<metrics::MetricsProvider>( + new metrics::ScreenInfoMetricsProvider)); + + drive_metrics_provider_ = new metrics::DriveMetricsProvider( + web::WebThread::GetTaskRunnerForThread(web::WebThread::FILE), + ios::FILE_LOCAL_STATE); + metrics_service_->RegisterMetricsProvider( + scoped_ptr<metrics::MetricsProvider>(drive_metrics_provider_)); + + profiler_metrics_provider_ = + new metrics::ProfilerMetricsProvider(base::Bind(&IsCellularLogicEnabled)); + metrics_service_->RegisterMetricsProvider( + scoped_ptr<metrics::MetricsProvider>(profiler_metrics_provider_)); + + metrics_service_->RegisterMetricsProvider( + scoped_ptr<metrics::MetricsProvider>( + new metrics::CallStackProfileMetricsProvider)); + + metrics_service_->RegisterMetricsProvider( + scoped_ptr<metrics::MetricsProvider>( + SigninStatusMetricsProvider::CreateInstance(make_scoped_ptr( + new IOSChromeSigninStatusMetricsProviderDelegate)))); + + scoped_ptr<metrics::MetricsProvider> ios_stability_metrics_provider( + new IOSStabilityMetricsProvider(metrics_service_.get())); + if (ios_stability_metrics_provider) { + metrics_service_->RegisterMetricsProvider( + ios_stability_metrics_provider.Pass()); + } else { + NOTREACHED() << "No IOSStabilityMetricsProvider registered."; + } +} + +void IOSChromeMetricsServiceClient::OnInitTaskGotDriveMetrics() { + finished_init_task_callback_.Run(); +} + +bool IOSChromeMetricsServiceClient::ShouldIncludeProfilerDataInLog() { + // Upload profiler data at most once per session. + if (has_uploaded_profiler_data_) + return false; + + // For each log, flip a fair coin. Thus, profiler data is sent with the first + // log with probability 50%, with the second log with probability 25%, and so + // on. As a result, uploaded data is biased toward earlier logs. + // TODO(isherman): Explore other possible algorithms, and choose one that + // might be more appropriate. For example, it might be reasonable to include + // profiler data with some fixed probability, so that a given client might + // upload profiler data more than once; but on average, clients won't upload + // too much data. + if (base::RandDouble() < 0.5) + return false; + + has_uploaded_profiler_data_ = true; + return true; +} + +void IOSChromeMetricsServiceClient::ReceivedProfilerData( + const metrics::ProfilerDataAttributes& attributes, + const tracked_objects::ProcessDataPhaseSnapshot& process_data_phase, + const metrics::ProfilerEvents& past_events) { + profiler_metrics_provider_->RecordProfilerData( + process_data_phase, attributes.process_id, attributes.process_type, + attributes.profiling_phase, attributes.phase_start - start_time_, + attributes.phase_finish - start_time_, past_events); +} + +void IOSChromeMetricsServiceClient::FinishedReceivingProfilerData() { + CollectFinalHistograms(); +} + +void IOSChromeMetricsServiceClient::CollectFinalHistograms() { + DCHECK(thread_checker_.CalledOnValidThread()); + + // TODO(ios): Try to extract the flow below into a utility function that is + // shared between the iOS port's usage and + // ChromeMetricsServiceClient::CollectFinalHistograms()'s usage of + // MetricsMemoryDetails. + scoped_ptr<base::ProcessMetrics> process_metrics( + base::ProcessMetrics::CreateProcessMetrics( + base::GetCurrentProcessHandle())); + UMA_HISTOGRAM_MEMORY_KB("Memory.Browser", + process_metrics->GetWorkingSetSize() / 1024); + collect_final_metrics_done_callback_.Run(); +} + +void IOSChromeMetricsServiceClient::RegisterForNotifications() { + tab_parented_subscription_ = + TabParentingGlobalObserver::GetInstance()->RegisterCallback( + base::Bind(&IOSChromeMetricsServiceClient::OnTabParented, + base::Unretained(this))); + omnibox_url_opened_subscription_ = + OmniboxEventGlobalTracker::GetInstance()->RegisterCallback( + base::Bind(&IOSChromeMetricsServiceClient::OnURLOpenedFromOmnibox, + base::Unretained(this))); +} + +void IOSChromeMetricsServiceClient::OnTabParented(web::WebState* web_state) { + metrics_service_->OnApplicationNotIdle(); +} + +void IOSChromeMetricsServiceClient::OnURLOpenedFromOmnibox(OmniboxLog* log) { + metrics_service_->OnApplicationNotIdle(); +}
diff --git a/ios/chrome/browser/metrics/ios_chrome_metrics_service_client.h b/ios/chrome/browser/metrics/ios_chrome_metrics_service_client.h new file mode 100644 index 0000000..bc9842f --- /dev/null +++ b/ios/chrome/browser/metrics/ios_chrome_metrics_service_client.h
@@ -0,0 +1,168 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_METRICS_IOS_CHROME_METRICS_SERVICE_CLIENT_H_ +#define IOS_CHROME_BROWSER_METRICS_IOS_CHROME_METRICS_SERVICE_CLIENT_H_ + +#include <string> + +#include "base/basictypes.h" +#include "base/callback.h" +#include "base/memory/scoped_ptr.h" +#include "base/memory/weak_ptr.h" +#include "base/threading/thread_checker.h" +#include "components/metrics/metrics_service_client.h" +#include "components/metrics/profiler/tracking_synchronizer_observer.h" +#include "components/omnibox/browser/omnibox_event_global_tracker.h" +#include "ios/web/public/web_state/global_web_state_observer.h" + +class IOSChromeStabilityMetricsProvider; +class PrefRegistrySimple; +class PrefService; + +namespace base { +class FilePath; +} // namespace base + +namespace metrics { +class DriveMetricsProvider; +class MetricsService; +class MetricsStateManager; +class ProfilerMetricsProvider; +} // namespace metrics + +// IOSChromeMetricsServiceClient provides an implementation of +// MetricsServiceClient that depends on //ios/chrome/. +class IOSChromeMetricsServiceClient + : public metrics::MetricsServiceClient, + public metrics::TrackingSynchronizerObserver, + public web::GlobalWebStateObserver { + public: + ~IOSChromeMetricsServiceClient() override; + + // Factory function. + static scoped_ptr<IOSChromeMetricsServiceClient> Create( + metrics::MetricsStateManager* state_manager, + PrefService* local_state); + + // Registers local state prefs used by this class. + static void RegisterPrefs(PrefRegistrySimple* registry); + + // metrics::MetricsServiceClient: + void SetMetricsClientId(const std::string& client_id) override; + void OnRecordingDisabled() override; + bool IsOffTheRecordSessionActive() override; + int32 GetProduct() override; + std::string GetApplicationLocale() override; + bool GetBrand(std::string* brand_code) override; + metrics::SystemProfileProto::Channel GetChannel() override; + std::string GetVersionString() override; + void OnLogUploadComplete() override; + void InitializeSystemProfileMetrics( + const base::Closure& done_callback) override; + void CollectFinalMetricsForLog(const base::Closure& done_callback) override; + scoped_ptr<metrics::MetricsLogUploader> CreateUploader( + const base::Callback<void(int)>& on_upload_complete) override; + base::TimeDelta GetStandardUploadInterval() override; + base::string16 GetRegistryBackupKey() override; + + // web::GlobalWebStateObserver: + void WebStateDidStartLoading(web::WebState* web_state) override; + void WebStateDidStopLoading(web::WebState* web_state) override; + + metrics::MetricsService* metrics_service() { return metrics_service_.get(); } + + // Records an unexpected renderer (web) process termination. + // This path only exists on iOS because the other platforms use the (now + // deprecated) content::Notification system to get this information into the + // stability provider. + void LogRendererProcessCrash(); + + private: + explicit IOSChromeMetricsServiceClient( + metrics::MetricsStateManager* state_manager); + + // Completes the two-phase initialization of IOSChromeMetricsServiceClient. + void Initialize(); + + // Called after the drive metrics init task has been completed that continues + // the init task by loading profiler data. + void OnInitTaskGotDriveMetrics(); + + // Returns true iff profiler data should be included in the next metrics log. + // NOTE: This method is probabilistic and also updates internal state as a + // side-effect when called, so it should only be called once per log. + bool ShouldIncludeProfilerDataInLog(); + + // TrackingSynchronizerObserver: + void ReceivedProfilerData( + const metrics::ProfilerDataAttributes& attributes, + const tracked_objects::ProcessDataPhaseSnapshot& process_data_phase, + const metrics::ProfilerEvents& past_profiler_events) override; + void FinishedReceivingProfilerData() override; + + // Callbacks for various stages of final log info collection. Do not call + // these directly. + void CollectFinalHistograms(); + + // Registers |this| as an observer for notifications which indicate that a + // user is performing work. This is useful to allow some features to sleep, + // until the machine becomes active, such as precluding UMA uploads unless + // there was recent activity. + void RegisterForNotifications(); + + // Called when a tab is parented. + void OnTabParented(web::WebState* web_state); + + // Called when a URL is opened from the Omnibox. + void OnURLOpenedFromOmnibox(OmniboxLog* log); + + base::ThreadChecker thread_checker_; + + // Weak pointer to the MetricsStateManager. + metrics::MetricsStateManager* metrics_state_manager_; + + // The MetricsService that |this| is a client of. + scoped_ptr<metrics::MetricsService> metrics_service_; + + // The IOSChromeStabilityMetricsProvider instance that was registered with + // MetricsService. Has the same lifetime as |metrics_service_|. + IOSChromeStabilityMetricsProvider* stability_metrics_provider_; + + // Saved callback received from CollectFinalMetricsForLog(). + base::Closure collect_final_metrics_done_callback_; + + // The ProfilerMetricsProvider instance that was registered with + // MetricsService. Has the same lifetime as |metrics_service_|. + metrics::ProfilerMetricsProvider* profiler_metrics_provider_; + + // The DriveMetricsProvider instance that was registered with MetricsService. + // Has the same lifetime as |metrics_service_|. + metrics::DriveMetricsProvider* drive_metrics_provider_; + + // Callback that is called when initial metrics gathering is complete. + base::Closure finished_init_task_callback_; + + // Time of this object's creation. + const base::TimeTicks start_time_; + + // Subscription for receiving callbacks that a tab was parented. + scoped_ptr<base::CallbackList<void(web::WebState*)>::Subscription> + tab_parented_subscription_; + + // Subscription for receiving callbacks that a URL was opened from the + // omnibox. + scoped_ptr<base::CallbackList<void(OmniboxLog*)>::Subscription> + omnibox_url_opened_subscription_; + + // Whether this client has already uploaded profiler data during this session. + // Profiler data is uploaded at most once per session. + bool has_uploaded_profiler_data_; + + base::WeakPtrFactory<IOSChromeMetricsServiceClient> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(IOSChromeMetricsServiceClient); +}; + +#endif // IOS_CHROME_BROWSER_METRICS_IOS_CHROME_METRICS_SERVICE_CLIENT_H_
diff --git a/ios/chrome/ios_chrome.gyp b/ios/chrome/ios_chrome.gyp index 9a156121..9a63991 100644 --- a/ios/chrome/ios_chrome.gyp +++ b/ios/chrome/ios_chrome.gyp
@@ -288,6 +288,8 @@ 'browser/metrics/field_trial_synchronizer.h', 'browser/metrics/ios_chrome_metrics_service_accessor.cc', 'browser/metrics/ios_chrome_metrics_service_accessor.h', + 'browser/metrics/ios_chrome_metrics_service_client.cc', + 'browser/metrics/ios_chrome_metrics_service_client.h', 'browser/metrics/ios_chrome_stability_metrics_provider.cc', 'browser/metrics/ios_chrome_stability_metrics_provider.h', 'browser/metrics/ios_stability_metrics_provider.h',
diff --git a/ios/web/ios_web.gyp b/ios/web/ios_web.gyp index a1ab0fff..891985a 100644 --- a/ios/web/ios_web.gyp +++ b/ios/web/ios_web.gyp
@@ -269,6 +269,8 @@ 'web_state/ui/crw_web_controller_container_view.h', 'web_state/ui/crw_web_controller_container_view.mm', 'web_state/ui/crw_web_view_content_view.mm', + 'web_state/ui/crw_wk_script_message_router.h', + 'web_state/ui/crw_wk_script_message_router.mm', 'web_state/ui/crw_wk_simple_web_view_controller.h', 'web_state/ui/crw_wk_simple_web_view_controller.mm', 'web_state/ui/crw_wk_web_view_crash_detector.h',
diff --git a/ios/web/ios_web_unittests.gyp b/ios/web/ios_web_unittests.gyp index f6df39f..8c7c517b 100644 --- a/ios/web/ios_web_unittests.gyp +++ b/ios/web/ios_web_unittests.gyp
@@ -68,6 +68,7 @@ 'web_state/ui/crw_web_controller_container_view_unittest.mm', 'web_state/ui/crw_web_controller_observer_unittest.mm', 'web_state/ui/crw_web_controller_unittest.mm', + 'web_state/ui/crw_wk_script_message_router_unittest.mm', 'web_state/ui/crw_wk_simple_web_view_controller_unittest.mm', 'web_state/ui/crw_wk_web_view_crash_detector_unittest.mm', 'web_state/ui/web_view_js_utils_unittest.mm',
diff --git a/ios/web/web_state/ui/crw_web_controller_unittest.mm b/ios/web/web_state/ui/crw_web_controller_unittest.mm index b0e29973..980b135d 100644 --- a/ios/web/web_state/ui/crw_web_controller_unittest.mm +++ b/ios/web/web_state/ui/crw_web_controller_unittest.mm
@@ -381,7 +381,6 @@ id result = [[OCMockObject mockForClass:[WKWebView class]] retain]; // Called by resetInjectedWebView - [[result stub] configuration]; [[result stub] backForwardList]; [[result stub] setNavigationDelegate:OCMOCK_ANY]; [[result stub] setUIDelegate:OCMOCK_ANY];
diff --git a/ios/web/web_state/ui/crw_wk_script_message_router.h b/ios/web/web_state/ui/crw_wk_script_message_router.h new file mode 100644 index 0000000..bb6b2a2d --- /dev/null +++ b/ios/web/web_state/ui/crw_wk_script_message_router.h
@@ -0,0 +1,43 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_WEB_WEB_STATE_UI_CRW_WK_SCRIPT_MESSAGE_ROUTER_H_ +#define IOS_WEB_WEB_STATE_UI_CRW_WK_SCRIPT_MESSAGE_ROUTER_H_ + +#import <WebKit/WebKit.h> + +// WKUserContentController wrapper that allows adding multiple message handlers +// for the same message name. CRWWKScriptMessageRouter will route the messages +// from the underlying user content controller to a designated reciever by +// matching the message's name and webView. +@interface CRWWKScriptMessageRouter : NSObject + +// Underlying WKUserContentController. +@property(nonatomic, readonly) WKUserContentController* userContentController; + +// Designated initializer. |userContentController| must not be nil. +- (instancetype)initWithUserContentController: + (WKUserContentController*)userContentController NS_DESIGNATED_INITIALIZER; + +- (instancetype)init NS_UNAVAILABLE; + +// Sets a script message handler. Multiple message handlers can be added for +// the same message name and long as |webView| are different. Setting |handler| +// for the same |name| and |webView| pair is an error. |handler| will be called +// if WKScriptMessage sent by WKUserContentController will match both the |name| +// and the |webView|. +- (void)setScriptMessageHandler:(void (^)(WKScriptMessage*))handler + name:(NSString*)messageName + webView:(WKWebView*)webView; + +// Removes a specific message handler. +- (void)removeScriptMessageHandlerForName:(NSString*)messageName + webView:(WKWebView*)webView; + +// Removes all message handlers for the given |webView|. +- (void)removeAllScriptMessageHandlersForWebView:(WKWebView*)webView; + +@end + +#endif // IOS_WEB_WEB_STATE_UI_CRW_WK_SCRIPT_MESSAGE_ROUTER_H_
diff --git a/ios/web/web_state/ui/crw_wk_script_message_router.mm b/ios/web/web_state/ui/crw_wk_script_message_router.mm new file mode 100644 index 0000000..5699abd --- /dev/null +++ b/ios/web/web_state/ui/crw_wk_script_message_router.mm
@@ -0,0 +1,113 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/web/web_state/ui/crw_wk_script_message_router.h" + +#import "base/logging.h" +#import "base/mac/scoped_nsobject.h" + +@interface CRWWKScriptMessageRouter ()<WKScriptMessageHandler> + +// Removes a specific message handler. Does nothing if handler does not exist. +- (void)tryRemoveScriptMessageHandlerForName:(NSString*)messageName + webView:(WKWebView*)webView; + +@end + +@implementation CRWWKScriptMessageRouter { + // Two level map of registed message handlers. Keys are message names and + // values are more maps (where keys are web views and values are handlers). + base::scoped_nsobject<NSMutableDictionary> _handlers; + // Wrapped WKUserContentController. + base::scoped_nsobject<WKUserContentController> _userContentController; +} + +#pragma mark - +#pragma mark Interface + +- (WKUserContentController*)userContentController { + return _userContentController.get(); +} + +- (instancetype)init { + NOTREACHED(); + return nil; +} + +- (instancetype)initWithUserContentController: + (WKUserContentController*)userContentController { + DCHECK(userContentController); + if ((self = [super init])) { + _handlers.reset([[NSMutableDictionary alloc] init]); + _userContentController.reset([userContentController retain]); + } + return self; +} + +- (void)setScriptMessageHandler:(void (^)(WKScriptMessage*))handler + name:(NSString*)messageName + webView:(WKWebView*)webView { + DCHECK(handler); + DCHECK(messageName); + DCHECK(webView); + + NSMapTable* webViewToHandlerMap = [_handlers objectForKey:messageName]; + if (!webViewToHandlerMap) { + webViewToHandlerMap = + [NSMapTable mapTableWithKeyOptions:NSPointerFunctionsStrongMemory + valueOptions:NSPointerFunctionsCopyIn]; + [_handlers setObject:webViewToHandlerMap forKey:messageName]; + [_userContentController addScriptMessageHandler:self name:messageName]; + } + DCHECK(![webViewToHandlerMap objectForKey:webView]); + [webViewToHandlerMap setObject:handler forKey:webView]; +} + +- (void)removeScriptMessageHandlerForName:(NSString*)messageName + webView:(WKWebView*)webView { + DCHECK(messageName); + DCHECK(webView); + DCHECK([[_handlers objectForKey:messageName] objectForKey:webView]); + [self tryRemoveScriptMessageHandlerForName:messageName webView:webView]; +} + +- (void)removeAllScriptMessageHandlersForWebView:(WKWebView*)webView { + DCHECK(webView); + for (NSString* messageName in [_handlers allKeys]) { + [self tryRemoveScriptMessageHandlerForName:messageName webView:webView]; + } +} + +#pragma mark - +#pragma mark WKScriptMessageHandler + +- (void)userContentController:(WKUserContentController*)userContentController + didReceiveScriptMessage:(WKScriptMessage*)message { + NSMapTable* webViewToHandlerMap = [_handlers objectForKey:message.name]; + DCHECK(webViewToHandlerMap); + id handler = [webViewToHandlerMap objectForKey:message.webView]; + if (handler) { + // Web process can send messages even if web view was reset and + // script message handler has been removed from the router. + ((void (^)(WKScriptMessage*))handler)(message); + } +} + +#pragma mark - +#pragma mark Implementation + +- (void)tryRemoveScriptMessageHandlerForName:(NSString*)messageName + webView:(WKWebView*)webView { + NSMapTable* webViewToHandlerMap = [_handlers objectForKey:messageName]; + if (![webViewToHandlerMap objectForKey:webView]) + return; + if (webViewToHandlerMap.count == 1) { + [_handlers removeObjectForKey:messageName]; + [_userContentController removeScriptMessageHandlerForName:messageName]; + } else { + [webViewToHandlerMap removeObjectForKey:webView]; + } +} + +@end
diff --git a/ios/web/web_state/ui/crw_wk_script_message_router_unittest.mm b/ios/web/web_state/ui/crw_wk_script_message_router_unittest.mm new file mode 100644 index 0000000..a638b8e --- /dev/null +++ b/ios/web/web_state/ui/crw_wk_script_message_router_unittest.mm
@@ -0,0 +1,209 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/web/web_state/ui/crw_wk_script_message_router.h" + +#include "base/mac/scoped_block.h" +#include "base/mac/scoped_nsobject.h" +#include "ios/web/public/test/test_browser_state.h" +#import "ios/web/public/test/test_web_client.h" +#include "ios/web/public/test/web_test_util.h" +#include "ios/web/test/web_test.h" +#include "third_party/ocmock/OCMock/OCMock.h" +#include "third_party/ocmock/gtest_support.h" + +namespace { + +// Returns WKScriptMessage mock. +id GetScriptMessageMock(WKWebView* web_view, NSString* name) { + id result = [OCMockObject mockForClass:[WKScriptMessage class]]; + [[[result stub] andReturn:web_view] webView]; + [[[result stub] andReturn:name] name]; + return result; +} + +// Test fixture for CRWWKScriptMessageRouter. +class CRWWKScriptMessageRouterTest : public web::WebTest { + protected: + void SetUp() override { + CR_TEST_REQUIRES_WK_WEB_VIEW(); + web::SetWebClient(&web_client_); + // Mock WKUserContentController object. + controller_mock_.reset( + [[OCMockObject mockForClass:[WKUserContentController class]] retain]); + [controller_mock_ setExpectationOrderMatters:YES]; + + // Create testable CRWWKScriptMessageRouter. + router_.reset(static_cast<id<WKScriptMessageHandler>>( + [[CRWWKScriptMessageRouter alloc] + initWithUserContentController:controller_mock_])); + + // Prepare test data. + handler1_.reset([^{ + } copy]); + handler2_.reset([^{ + } copy]); + handler3_.reset([^{ + } copy]); + name1_.reset([@"name1" copy]); + name2_.reset([@"name2" copy]); + name3_.reset([@"name3" copy]); + web_view1_.reset(web::CreateWKWebView(CGRectZero, &browser_state_)); + web_view2_.reset(web::CreateWKWebView(CGRectZero, &browser_state_)); + web_view3_.reset(web::CreateWKWebView(CGRectZero, &browser_state_)); + } + void TearDown() override { + EXPECT_OCMOCK_VERIFY(controller_mock_); + web::SetWebClient(nullptr); + } + + // WKUserContentController mock used to create testable router. + base::scoped_nsobject<id> controller_mock_; + + // CRWWKScriptMessageRouter set up for testing. + base::scoped_nsobject<id> router_; + + // Tests data. + typedef void (^WKScriptMessageHandler)(WKScriptMessage*); + base::mac::ScopedBlock<WKScriptMessageHandler> handler1_; + base::mac::ScopedBlock<WKScriptMessageHandler> handler2_; + base::mac::ScopedBlock<WKScriptMessageHandler> handler3_; + base::scoped_nsobject<NSString> name1_; + base::scoped_nsobject<NSString> name2_; + base::scoped_nsobject<NSString> name3_; + base::scoped_nsobject<WKWebView> web_view1_; + base::scoped_nsobject<WKWebView> web_view2_; + base::scoped_nsobject<WKWebView> web_view3_; + + private: + // WebClient and BrowserState for testing. + web::TestWebClient web_client_; + web::TestBrowserState browser_state_; +}; + +// Tests CRWWKScriptMessageRouter designated initializer. +TEST_F(CRWWKScriptMessageRouterTest, Initialization) { + CR_TEST_REQUIRES_WK_WEB_VIEW(); + + EXPECT_TRUE(router_); +} + +// Tests registration/deregistation of message handlers. +TEST_F(CRWWKScriptMessageRouterTest, HandlerRegistration) { + CR_TEST_REQUIRES_WK_WEB_VIEW(); + + [[controller_mock_ expect] addScriptMessageHandler:router_ name:name1_]; + [[controller_mock_ expect] addScriptMessageHandler:router_ name:name2_]; + + [[controller_mock_ expect] removeScriptMessageHandlerForName:name1_]; + [[controller_mock_ expect] removeScriptMessageHandlerForName:name2_]; + + [router_ setScriptMessageHandler:handler1_ name:name1_ webView:web_view1_]; + [router_ setScriptMessageHandler:handler2_ name:name2_ webView:web_view2_]; + [router_ setScriptMessageHandler:handler3_ name:name2_ webView:web_view3_]; + + [router_ removeScriptMessageHandlerForName:name1_ webView:web_view1_]; + [router_ removeScriptMessageHandlerForName:name2_ webView:web_view2_]; + [router_ removeScriptMessageHandlerForName:name2_ webView:web_view3_]; +} + +// Tests registration of message handlers. Test ensures that +// WKScriptMessageHandler is not removed if CRWWKScriptMessageRouter has valid +// message handlers. +TEST_F(CRWWKScriptMessageRouterTest, HandlerRegistrationLeak) { + CR_TEST_REQUIRES_WK_WEB_VIEW(); + + [[controller_mock_ expect] addScriptMessageHandler:router_ name:name1_]; + + // -removeScriptMessageHandlerForName must not be called. + + [router_ setScriptMessageHandler:handler1_ name:name1_ webView:web_view1_]; + [router_ setScriptMessageHandler:handler2_ name:name1_ webView:web_view2_]; + + [router_ removeScriptMessageHandlerForName:name1_ webView:web_view1_]; +} + +// Tests deregistation of all message handlers. +TEST_F(CRWWKScriptMessageRouterTest, RemoveAllHandlers) { + CR_TEST_REQUIRES_WK_WEB_VIEW(); + + [[controller_mock_ expect] addScriptMessageHandler:router_ name:name1_]; + [[controller_mock_ expect] addScriptMessageHandler:router_ name:name2_]; + + [[controller_mock_ expect] removeScriptMessageHandlerForName:name2_]; + [[controller_mock_ expect] removeScriptMessageHandlerForName:name1_]; + + [router_ setScriptMessageHandler:handler1_ name:name1_ webView:web_view1_]; + [router_ setScriptMessageHandler:handler2_ name:name2_ webView:web_view1_]; + [router_ setScriptMessageHandler:handler3_ name:name1_ webView:web_view2_]; + + [router_ removeAllScriptMessageHandlersForWebView:web_view1_]; + [router_ removeAllScriptMessageHandlersForWebView:web_view2_]; +} + +// Tests deregistation of all message handlers. Test ensures that +// WKScriptMessageHandler is not removed if CRWWKScriptMessageRouter has valid +// message handlers. +TEST_F(CRWWKScriptMessageRouterTest, RemoveAllHandlersLeak) { + CR_TEST_REQUIRES_WK_WEB_VIEW(); + + [[controller_mock_ expect] addScriptMessageHandler:router_ name:name1_]; + [[controller_mock_ expect] addScriptMessageHandler:router_ name:name2_]; + [[controller_mock_ expect] addScriptMessageHandler:router_ name:name3_]; + + [[controller_mock_ expect] removeScriptMessageHandlerForName:name2_]; + // -removeScriptMessageHandlerForName:name1_ must not be called. + + [router_ setScriptMessageHandler:handler1_ name:name1_ webView:web_view1_]; + [router_ setScriptMessageHandler:handler2_ name:name2_ webView:web_view1_]; + [router_ setScriptMessageHandler:handler2_ name:name3_ webView:web_view2_]; + [router_ setScriptMessageHandler:handler3_ name:name1_ webView:web_view2_]; + + [router_ removeAllScriptMessageHandlersForWebView:web_view1_]; +} + +// Tests proper routing of WKScriptMessage object depending on message name and +// web view. +TEST_F(CRWWKScriptMessageRouterTest, Routing) { + CR_TEST_REQUIRES_WK_WEB_VIEW(); + + // It's expected that messages handlers will be called once and in order. + __block NSInteger last_called_handler = 0; + id message1 = GetScriptMessageMock(web_view1_, name1_); + id handler1 = ^(WKScriptMessage* message) { + EXPECT_EQ(0, last_called_handler); + EXPECT_EQ(message1, message); + last_called_handler = 1; + }; + id message2 = GetScriptMessageMock(web_view2_, name2_); + id handler2 = ^(WKScriptMessage* message) { + EXPECT_EQ(1, last_called_handler); + EXPECT_EQ(message2, message); + last_called_handler = 2; + }; + id message3 = GetScriptMessageMock(web_view3_, name2_); + id handler3 = ^(WKScriptMessage* message) { + EXPECT_EQ(2, last_called_handler); + EXPECT_EQ(message3, message); + last_called_handler = 3; + }; + + [[controller_mock_ expect] addScriptMessageHandler:router_ name:name1_]; + [[controller_mock_ expect] addScriptMessageHandler:router_ name:name2_]; + + [router_ setScriptMessageHandler:handler1 name:name1_ webView:web_view1_]; + [router_ setScriptMessageHandler:handler2 name:name2_ webView:web_view2_]; + [router_ setScriptMessageHandler:handler3 name:name2_ webView:web_view3_]; + + [router_ userContentController:controller_mock_ + didReceiveScriptMessage:message1]; + [router_ userContentController:controller_mock_ + didReceiveScriptMessage:message2]; + [router_ userContentController:controller_mock_ + didReceiveScriptMessage:message3]; + + EXPECT_EQ(3, last_called_handler); +} + +} // namespace
diff --git a/ios/web/web_state/ui/crw_wk_web_view_web_controller.mm b/ios/web/web_state/ui/crw_wk_web_view_web_controller.mm index e5c88664..db9dc92 100644 --- a/ios/web/web_state/ui/crw_wk_web_view_web_controller.mm +++ b/ios/web/web_state/ui/crw_wk_web_view_web_controller.mm
@@ -32,8 +32,8 @@ #import "ios/web/web_state/error_translation_util.h" #include "ios/web/web_state/frame_info.h" #import "ios/web/web_state/js/crw_js_window_id_manager.h" -#import "ios/web/web_state/js/page_script_util.h" #import "ios/web/web_state/ui/crw_web_controller+protected.h" +#import "ios/web/web_state/ui/crw_wk_script_message_router.h" #import "ios/web/web_state/ui/crw_wk_web_view_crash_detector.h" #import "ios/web/web_state/ui/web_view_js_utils.h" #import "ios/web/web_state/ui/wk_back_forward_list_item_holder.h" @@ -82,9 +82,7 @@ } // namespace -@interface CRWWKWebViewWebController () <WKNavigationDelegate, - WKScriptMessageHandler, - WKUIDelegate> { +@interface CRWWKWebViewWebController ()<WKNavigationDelegate, WKUIDelegate> { // The WKWebView managed by this instance. base::scoped_nsobject<WKWebView> _wkWebView; @@ -264,9 +262,8 @@ // _documentURL, and informs the superclass of the change. - (void)URLDidChangeWithoutDocumentChange:(const GURL&)URL; -// Returns new autoreleased instance of WKUserContentController which has -// early page script. -- (WKUserContentController*)createUserContentController; +// Called when web controller receives a new message from the web page. +- (void)didReceiveScriptMessage:(WKScriptMessage*)message; // Attempts to handle a script message. Returns YES on success, NO otherwise. - (BOOL)respondToWKScriptMessage:(WKScriptMessage*)scriptMessage; @@ -643,11 +640,6 @@ - (void)ensureWebViewCreatedWithConfiguration:(WKWebViewConfiguration*)config { if (!_wkWebView) { - // Use a separate userContentController for each web view. - // WKUserContentController does not allow adding multiple script message - // handlers for the same name, hence userContentController can't be shared - // between all web views. - config.userContentController = [self createUserContentController]; [self setWebView:[self createWebViewWithConfiguration:config]]; // Notify super class about created web view. -webViewDidChange is not // called from -setWebView:scriptMessageRouter: as the latter used in unit @@ -667,10 +659,13 @@ DCHECK_NE(_wkWebView.get(), webView); // Unwind the old web view. - WKUserContentController* oldContentController = - [[_wkWebView configuration] userContentController]; - [oldContentController removeScriptMessageHandlerForName:kScriptMessageName]; - [oldContentController removeScriptMessageHandlerForName:kScriptImmediateName]; + // TODO(eugenebut): Remove CRWWKScriptMessageRouter once crbug.com/543374 is + // fixed. + CRWWKScriptMessageRouter* messageRouter = + [self webViewConfigurationProvider].GetScriptMessageRouter(); + if (_wkWebView) { + [messageRouter removeAllScriptMessageHandlersForWebView:_wkWebView]; + } [_wkWebView setNavigationDelegate:nil]; [_wkWebView setUIDelegate:nil]; for (NSString* keyPath in self.wkWebViewObservers) { @@ -681,10 +676,18 @@ _wkWebView.reset([webView retain]); // Set up the new web view. - WKUserContentController* newContentController = - [[_wkWebView configuration] userContentController]; - [newContentController addScriptMessageHandler:self name:kScriptMessageName]; - [newContentController addScriptMessageHandler:self name:kScriptImmediateName]; + if (webView) { + base::WeakNSObject<CRWWKWebViewWebController> weakSelf(self); + void (^messageHandler)(WKScriptMessage*) = ^(WKScriptMessage* message) { + [weakSelf didReceiveScriptMessage:message]; + }; + [messageRouter setScriptMessageHandler:messageHandler + name:kScriptMessageName + webView:webView]; + [messageRouter setScriptMessageHandler:messageHandler + name:kScriptImmediateName + webView:webView]; + } [_wkWebView setNavigationDelegate:self]; [_wkWebView setUIDelegate:self]; for (NSString* keyPath in self.wkWebViewObservers) { @@ -938,19 +941,7 @@ } } -- (WKUserContentController*)createUserContentController { - WKUserContentController* result = - [[[WKUserContentController alloc] init] autorelease]; - base::scoped_nsobject<WKUserScript> script([[WKUserScript alloc] - initWithSource:web::GetEarlyPageScript(web::WK_WEB_VIEW_TYPE) - injectionTime:WKUserScriptInjectionTimeAtDocumentStart - forMainFrameOnly:YES]); - [result addUserScript:script]; - return result; -} - -- (void)userContentController:(WKUserContentController*)userContentController - didReceiveScriptMessage:(WKScriptMessage*)message { +- (void)didReceiveScriptMessage:(WKScriptMessage*)message { // Broken out into separate method to catch errors. // TODO(jyquinn): Evaluate whether this is necessary for WKWebView. if (![self respondToWKScriptMessage:message]) {
diff --git a/ios/web/web_state/ui/wk_web_view_configuration_provider.h b/ios/web/web_state/ui/wk_web_view_configuration_provider.h index 32a4130d..1059e135 100644 --- a/ios/web/web_state/ui/wk_web_view_configuration_provider.h +++ b/ios/web/web_state/ui/wk_web_view_configuration_provider.h
@@ -9,6 +9,7 @@ #include "base/macros.h" #include "base/supports_user_data.h" +@class CRWWKScriptMessageRouter; @class WKWebViewConfiguration; namespace web { @@ -16,8 +17,9 @@ class BrowserState; // A provider class associated with a single web::BrowserState object. Manages -// the lifetime and performs setup of WKWebViewConfiguration instance. -// Not threadsafe. Must be used only on the main thread. +// the lifetime and performs setup of WKWebViewConfiguration and +// CRWWKScriptMessageRouter instances. Not threadsafe. Must be used only on the +// main thread. class WKWebViewConfigurationProvider : public base::SupportsUserData::Data { public: // Returns a provider for the given |browser_state|. Lazily attaches one if it @@ -32,9 +34,14 @@ // Callers must not retain the returned object. WKWebViewConfiguration* GetWebViewConfiguration(); - // Purges config object if it exists. When this method is called config and - // config's process pool must not be retained by anyone (this will be enforced - // in debug builds). + // Returns CRWWKScriptMessafeRouter associated with WKWebViewConfiguration. + // Lazily creates the router. Callers must not retain the returned object + // (this will be enforced in debug builds). + CRWWKScriptMessageRouter* GetScriptMessageRouter(); + + // Purges config and router objects if they exist. When this method is called + // config and config's process pool must not be retained by anyone (this will + // be enforced in debug builds). void Purge(); private: @@ -43,6 +50,7 @@ ~WKWebViewConfigurationProvider() override; base::scoped_nsobject<WKWebViewConfiguration> configuration_; + base::scoped_nsobject<CRWWKScriptMessageRouter> router_; // Result of |web::BrowserState::IsOffTheRecord| call. bool is_off_the_record_;
diff --git a/ios/web/web_state/ui/wk_web_view_configuration_provider.mm b/ios/web/web_state/ui/wk_web_view_configuration_provider.mm index d50a625..693b5184 100644 --- a/ios/web/web_state/ui/wk_web_view_configuration_provider.mm +++ b/ios/web/web_state/ui/wk_web_view_configuration_provider.mm
@@ -14,6 +14,7 @@ #import "ios/web/alloc_with_zone_interceptor.h" #include "ios/web/public/browser_state.h" #import "ios/web/web_state/js/page_script_util.h" +#import "ios/web/web_state/ui/crw_wk_script_message_router.h" #import "ios/web/web_state/web_view_internal_creation_util.h" #if !defined(NDEBUG) @@ -162,15 +163,30 @@ return [[configuration_ copy] autorelease]; } +CRWWKScriptMessageRouter* +WKWebViewConfigurationProvider::GetScriptMessageRouter() { + DCHECK([NSThread isMainThread]); + if (!router_) { + WKUserContentController* userContentController = + [GetWebViewConfiguration() userContentController]; + router_.reset([[CRWWKScriptMessageRouter alloc] + initWithUserContentController:userContentController]); + } + return router_; +} + void WKWebViewConfigurationProvider::Purge() { DCHECK([NSThread isMainThread]); #if !defined(NDEBUG) || !defined(DCHECK_ALWAYS_ON) // Matches DCHECK_IS_ON. base::WeakNSObject<id> weak_configuration(configuration_); + base::WeakNSObject<id> weak_router(router_); base::WeakNSObject<id> weak_process_pool([configuration_ processPool]); #endif // !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON) configuration_.reset(); - // Make sure that no one retains configuration and processPool. + router_.reset(); + // Make sure that no one retains configuration, router, processPool. DCHECK(!weak_configuration); + DCHECK(!weak_router); // TODO(shreyasv): Enable this DCHECK (crbug.com/522672). // DCHECK(!weak_process_pool); }
diff --git a/ios/web/web_state/ui/wk_web_view_configuration_provider_unittest.mm b/ios/web/web_state/ui/wk_web_view_configuration_provider_unittest.mm index a75bc03..7a1e099 100644 --- a/ios/web/web_state/ui/wk_web_view_configuration_provider_unittest.mm +++ b/ios/web/web_state/ui/wk_web_view_configuration_provider_unittest.mm
@@ -12,6 +12,7 @@ #include "ios/web/public/test/web_test_util.h" #include "ios/web/public/web_client.h" #import "ios/web/web_state/js/page_script_util.h" +#import "ios/web/web_state/ui/crw_wk_script_message_router.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest_mac.h" #include "testing/platform_test.h" @@ -131,19 +132,33 @@ provider.GetWebViewConfiguration().userContentController); } -// Tests that configuration is deallocated after |Purge| call. +// Tests that script message router is bound to correct user content controller. +TEST_F(WKWebViewConfigurationProviderTest, ScriptMessageRouter) { + CR_TEST_REQUIRES_WK_WEB_VIEW(); + + ASSERT_TRUE(GetProvider().GetWebViewConfiguration().userContentController); + EXPECT_EQ(GetProvider().GetWebViewConfiguration().userContentController, + GetProvider().GetScriptMessageRouter().userContentController); +} + +// Tests that both configuration and script message router are deallocated after +// |Purge| call. TEST_F(WKWebViewConfigurationProviderTest, Purge) { CR_TEST_REQUIRES_WK_WEB_VIEW(); base::WeakNSObject<id> config; + base::WeakNSObject<id> router; @autoreleasepool { // Make sure that resulting copy is deallocated. config.reset(GetProvider().GetWebViewConfiguration()); + router.reset(GetProvider().GetScriptMessageRouter()); ASSERT_TRUE(config); + ASSERT_TRUE(router); } - // No configuration after |Purge| call. + // No configuration and router after |Purge| call. GetProvider().Purge(); EXPECT_FALSE(config); + EXPECT_FALSE(router); } // Tests that configuration's userContentController has only one script with the
diff --git a/mandoline/ui/desktop_ui/browser_manager.cc b/mandoline/ui/desktop_ui/browser_manager.cc index 54d2558..bef4dd5 100644 --- a/mandoline/ui/desktop_ui/browser_manager.cc +++ b/mandoline/ui/desktop_ui/browser_manager.cc
@@ -5,8 +5,8 @@ #include "mandoline/ui/desktop_ui/browser_manager.h" #include "base/command_line.h" -#include "components/mus/public/cpp/view.h" -#include "components/mus/public/cpp/view_observer.h" +#include "components/mus/public/cpp/window.h" +#include "components/mus/public/cpp/window_observer.h" #include "mandoline/ui/desktop_ui/browser_window.h" namespace mandoline {
diff --git a/mandoline/ui/desktop_ui/browser_window.cc b/mandoline/ui/desktop_ui/browser_window.cc index 333728e..363320e 100644 --- a/mandoline/ui/desktop_ui/browser_window.cc +++ b/mandoline/ui/desktop_ui/browser_window.cc
@@ -8,8 +8,8 @@ #include "base/strings/string16.h" #include "base/strings/utf_string_conversions.h" #include "base/time/time.h" -#include "components/mus/public/cpp/scoped_view_ptr.h" -#include "components/mus/public/cpp/view_tree_host_factory.h" +#include "components/mus/public/cpp/scoped_window_ptr.h" +#include "components/mus/public/cpp/window_tree_host_factory.h" #include "mandoline/ui/desktop_ui/browser_commands.h" #include "mandoline/ui/desktop_ui/browser_manager.h" #include "mandoline/ui/desktop_ui/find_bar_view.h" @@ -84,7 +84,7 @@ web_view_(this) { mojo::ViewTreeHostClientPtr host_client; host_client_binding_.Bind(GetProxy(&host_client)); - mus::CreateViewTreeHost(host_factory, host_client.Pass(), this, &host_); + mus::CreateWindowTreeHost(host_factory, host_client.Pass(), this, &host_); } void BrowserWindow::LoadURL(const GURL& url) { @@ -107,7 +107,7 @@ void BrowserWindow::Close() { if (root_) - mus::ScopedViewPtr::DeleteViewOrViewManager(root_); + mus::ScopedWindowPtr::DeleteWindowOrWindowManager(root_); else delete this; } @@ -154,7 +154,7 @@ //////////////////////////////////////////////////////////////////////////////// // BrowserWindow, mus::ViewTreeDelegate implementation: -void BrowserWindow::OnEmbed(mus::View* root) { +void BrowserWindow::OnEmbed(mus::Window* root) { // BrowserWindow does not support being embedded more than once. CHECK(!root_); @@ -165,7 +165,7 @@ host_->SetTitle("Mandoline"); - content_ = root_->connection()->CreateView(); + content_ = root_->connection()->CreateWindow(); Init(root_); host_->SetSize(mojo::Size::From(gfx::Size(1280, 800))); @@ -211,7 +211,7 @@ } } -void BrowserWindow::OnConnectionLost(mus::ViewTreeConnection* connection) { +void BrowserWindow::OnConnectionLost(mus::WindowTreeConnection* connection) { root_ = nullptr; delete this; } @@ -369,14 +369,13 @@ //////////////////////////////////////////////////////////////////////////////// // BrowserWindow, private: -void BrowserWindow::Init(mus::View* root) { +void BrowserWindow::Init(mus::Window* root) { DCHECK_GT(root->viewport_metrics().device_pixel_ratio, 0); if (!aura_init_) - aura_init_.reset( - new views::AuraInit(root, app_->shell(), "mandoline_ui.pak")); + aura_init_.reset(new views::AuraInit(app_, "mandoline_ui.pak", root)); root_ = root; - omnibox_view_ = root_->connection()->CreateView(); + omnibox_view_ = root_->connection()->CreateWindow(); root_->AddChild(omnibox_view_); views::WidgetDelegateView* widget_delegate = new views::WidgetDelegateView;
diff --git a/mandoline/ui/desktop_ui/browser_window.h b/mandoline/ui/desktop_ui/browser_window.h index 0d487a4..2824c42 100644 --- a/mandoline/ui/desktop_ui/browser_window.h +++ b/mandoline/ui/desktop_ui/browser_window.h
@@ -5,8 +5,8 @@ #ifndef MANDOLINE_UI_DESKTOP_UI_BROWSER_WINDOW_H_ #define MANDOLINE_UI_DESKTOP_UI_BROWSER_WINDOW_H_ -#include "components/mus/public/cpp/view_tree_connection.h" -#include "components/mus/public/cpp/view_tree_delegate.h" +#include "components/mus/public/cpp/window_tree_connection.h" +#include "components/mus/public/cpp/window_tree_delegate.h" #include "components/mus/public/interfaces/view_tree_host.mojom.h" #include "components/web_view/public/cpp/web_view.h" #include "components/web_view/public/interfaces/web_view.mojom.h" @@ -32,7 +32,7 @@ class ProgressView; class ToolbarView; -class BrowserWindow : public mus::ViewTreeDelegate, +class BrowserWindow : public mus::WindowTreeDelegate, public mojo::ViewTreeHostClient, public web_view::mojom::WebViewClient, public ViewEmbedder, @@ -57,9 +57,9 @@ float DIPSToPixels(float value) const; - // Overridden from mus::ViewTreeDelegate: - void OnEmbed(mus::View* root) override; - void OnConnectionLost(mus::ViewTreeConnection* connection) override; + // Overridden from mus::WindowTreeDelegate: + void OnEmbed(mus::Window* root) override; + void OnConnectionLost(mus::WindowTreeConnection* connection) override; // Overridden from ViewTreeHostClient: void OnAccelerator(uint32_t id, mojo::EventPtr event) override; @@ -93,7 +93,7 @@ void OnDoFind(const std::string& find, bool forward) override; void OnHideFindBar() override; - void Init(mus::View* root); + void Init(mus::Window* root); void EmbedOmnibox(); mojo::ApplicationImpl* app_; @@ -104,9 +104,9 @@ ToolbarView* toolbar_view_; ProgressView* progress_bar_; FindBarView* find_bar_view_; - mus::View* root_; - mus::View* content_; - mus::View* omnibox_view_; + mus::Window* root_; + mus::Window* content_; + mus::Window* omnibox_view_; mojo::WeakBindingSet<ViewEmbedder> view_embedder_bindings_;
diff --git a/mandoline/ui/omnibox/omnibox_application.cc b/mandoline/ui/omnibox/omnibox_application.cc index 2579005..3c5491d 100644 --- a/mandoline/ui/omnibox/omnibox_application.cc +++ b/mandoline/ui/omnibox/omnibox_application.cc
@@ -6,9 +6,9 @@ #include "base/strings/string16.h" #include "base/strings/utf_string_conversions.h" -#include "components/mus/public/cpp/view.h" -#include "components/mus/public/cpp/view_tree_connection.h" -#include "components/mus/public/cpp/view_tree_delegate.h" +#include "components/mus/public/cpp/window.h" +#include "components/mus/public/cpp/window_tree_connection.h" +#include "components/mus/public/cpp/window_tree_delegate.h" #include "components/url_formatter/url_fixer.h" #include "mandoline/ui/desktop_ui/public/interfaces/view_embedder.mojom.h" #include "mojo/application/public/cpp/application_impl.h" @@ -27,7 +27,7 @@ //////////////////////////////////////////////////////////////////////////////// // OmniboxImpl -class OmniboxImpl : public mus::ViewTreeDelegate, +class OmniboxImpl : public mus::WindowTreeDelegate, public views::LayoutManager, public views::TextfieldController, public Omnibox { @@ -38,9 +38,9 @@ ~OmniboxImpl() override; private: - // Overridden from mus::ViewTreeDelegate: - void OnEmbed(mus::View* root) override; - void OnConnectionLost(mus::ViewTreeConnection* connection) override; + // Overridden from mus::WindowTreeDelegate: + void OnEmbed(mus::Window* root) override; + void OnConnectionLost(mus::WindowTreeConnection* connection) override; // Overridden from views::LayoutManager: gfx::Size GetPreferredSize(const views::View* view) const override; @@ -60,7 +60,7 @@ scoped_ptr<views::AuraInit> aura_init_; mojo::ApplicationImpl* app_; - mus::View* root_; + mus::Window* root_; mojo::String url_; views::Textfield* edit_; mojo::Binding<Omnibox> binding_; @@ -111,14 +111,13 @@ OmniboxImpl::~OmniboxImpl() {} //////////////////////////////////////////////////////////////////////////////// -// OmniboxImpl, mus::ViewTreeDelegate implementation: +// OmniboxImpl, mus::WindowTreeDelegate implementation: -void OmniboxImpl::OnEmbed(mus::View* root) { +void OmniboxImpl::OnEmbed(mus::Window* root) { root_ = root; if (!aura_init_.get()) { - aura_init_.reset( - new views::AuraInit(root, app_->shell(), "mandoline_ui.pak")); + aura_init_.reset(new views::AuraInit(app_, "mandoline_ui.pak", root_)); edit_ = new views::Textfield; edit_->set_controller(this); edit_->SetTextInputType(ui::TEXT_INPUT_TYPE_URL); @@ -150,7 +149,7 @@ ShowWindow(); } -void OmniboxImpl::OnConnectionLost(mus::ViewTreeConnection* connection) { +void OmniboxImpl::OnConnectionLost(mus::WindowTreeConnection* connection) { root_ = nullptr; } @@ -192,9 +191,9 @@ void OmniboxImpl::GetViewTreeClient( mojo::InterfaceRequest<mojo::ViewTreeClient> request) { - mus::ViewTreeConnection::Create( + mus::WindowTreeConnection::Create( this, request.Pass(), - mus::ViewTreeConnection::CreateType::DONT_WAIT_FOR_EMBED); + mus::WindowTreeConnection::CreateType::DONT_WAIT_FOR_EMBED); } void OmniboxImpl::ShowForURL(const mojo::String& url) {
diff --git a/mandoline/ui/phone_ui/phone_browser_application_delegate.cc b/mandoline/ui/phone_ui/phone_browser_application_delegate.cc index d2ac75b..ef3758d 100644 --- a/mandoline/ui/phone_ui/phone_browser_application_delegate.cc +++ b/mandoline/ui/phone_ui/phone_browser_application_delegate.cc
@@ -5,9 +5,9 @@ #include "mandoline/ui/phone_ui/phone_browser_application_delegate.h" #include "base/command_line.h" -#include "components/mus/public/cpp/view.h" -#include "components/mus/public/cpp/view_tree_connection.h" -#include "components/mus/public/cpp/view_tree_host_factory.h" +#include "components/mus/public/cpp/window.h" +#include "components/mus/public/cpp/window_tree_connection.h" +#include "components/mus/public/cpp/window_tree_host_factory.h" #include "mojo/application/public/cpp/application_connection.h" #include "mojo/application/public/cpp/application_impl.h" #include "mojo/converters/geometry/geometry_type_converters.h" @@ -47,7 +47,7 @@ break; } } - mus::CreateSingleViewTreeHost(app_, this, &host_); + mus::CreateSingleWindowTreeHost(app_, this, &host_); } bool PhoneBrowserApplicationDelegate::ConfigureIncomingConnection( @@ -66,12 +66,12 @@ } //////////////////////////////////////////////////////////////////////////////// -// PhoneBrowserApplicationDelegate, mus::ViewTreeDelegate implementation: +// PhoneBrowserApplicationDelegate, mus::WindowTreeDelegate implementation: -void PhoneBrowserApplicationDelegate::OnEmbed(mus::View* root) { +void PhoneBrowserApplicationDelegate::OnEmbed(mus::Window* root) { CHECK(!root_); root_ = root; - content_ = root->connection()->CreateView(); + content_ = root->connection()->CreateWindow(); root->AddChild(content_); content_->SetBounds(root->bounds()); content_->SetVisible(true); @@ -83,13 +83,13 @@ } void PhoneBrowserApplicationDelegate::OnConnectionLost( - mus::ViewTreeConnection* connection) {} + mus::WindowTreeConnection* connection) {} //////////////////////////////////////////////////////////////////////////////// -// PhoneBrowserApplicationDelegate, mus::ViewObserver implementation: +// PhoneBrowserApplicationDelegate, mus::WindowObserver implementation: -void PhoneBrowserApplicationDelegate::OnViewBoundsChanged( - mus::View* view, +void PhoneBrowserApplicationDelegate::OnWindowBoundsChanged( + mus::Window* view, const mojo::Rect& old_bounds, const mojo::Rect& new_bounds) { CHECK_EQ(view, root_);
diff --git a/mandoline/ui/phone_ui/phone_browser_application_delegate.h b/mandoline/ui/phone_ui/phone_browser_application_delegate.h index f310259..e21c225 100644 --- a/mandoline/ui/phone_ui/phone_browser_application_delegate.h +++ b/mandoline/ui/phone_ui/phone_browser_application_delegate.h
@@ -7,8 +7,8 @@ #include "base/macros.h" #include "base/memory/scoped_ptr.h" -#include "components/mus/public/cpp/view_observer.h" -#include "components/mus/public/cpp/view_tree_delegate.h" +#include "components/mus/public/cpp/window_observer.h" +#include "components/mus/public/cpp/window_tree_delegate.h" #include "components/mus/public/interfaces/view_tree_host.mojom.h" #include "components/web_view/public/cpp/web_view.h" #include "components/web_view/public/interfaces/web_view.mojom.h" @@ -27,8 +27,8 @@ class PhoneBrowserApplicationDelegate : public mojo::ApplicationDelegate, public LaunchHandler, - public mus::ViewTreeDelegate, - public mus::ViewObserver, + public mus::WindowTreeDelegate, + public mus::WindowObserver, public web_view::mojom::WebViewClient, public mojo::InterfaceFactory<LaunchHandler> { public: @@ -44,14 +44,14 @@ // Overridden from LaunchHandler: void LaunchURL(const mojo::String& url) override; - // Overridden from mus::ViewTreeDelegate: - void OnEmbed(mus::View* root) override; - void OnConnectionLost(mus::ViewTreeConnection* connection) override; + // Overridden from mus::WindowTreeDelegate: + void OnEmbed(mus::Window* root) override; + void OnConnectionLost(mus::WindowTreeConnection* connection) override; - // Overridden from mus::ViewObserver: - void OnViewBoundsChanged(mus::View* view, - const mojo::Rect& old_bounds, - const mojo::Rect& new_bounds) override; + // Overridden from mus::WindowObserver: + void OnWindowBoundsChanged(mus::Window* view, + const mojo::Rect& old_bounds, + const mojo::Rect& new_bounds) override; // Overridden from web_view::mojom::WebViewClient: void TopLevelNavigateRequest(mojo::URLRequestPtr request) override; @@ -73,8 +73,8 @@ mojo::ApplicationImpl* app_; mojo::ViewTreeHostPtr host_; - mus::View* root_; - mus::View* content_; + mus::Window* root_; + mus::Window* content_; web_view::WebView web_view_; mojo::String default_url_;
diff --git a/media/BUILD.gn b/media/BUILD.gn index aae2154..76c0fac 100644 --- a/media/BUILD.gn +++ b/media/BUILD.gn
@@ -56,6 +56,12 @@ "/DELAYLOAD:mfreadwrite.dll", ] } + if (media_use_ffmpeg && is_android) { + defines += [ + "ENABLE_MEDIA_PIPELINE_ON_ANDROID", + "DISABLE_FFMPEG_VIDEO_DECODERS", + ] + } } if (use_ozone) { @@ -364,6 +370,14 @@ } if (is_android) { + # On Android, FFmpeg is built without video decoders. We only + # support hardware video decoding. + if (media_use_ffmpeg) { + sources -= [ + "filters/ffmpeg_video_decoder.cc", + "filters/ffmpeg_video_decoder.h", + ] + } sources += [ "capture/video/android/video_capture_device_android.cc", "capture/video/android/video_capture_device_android.h", @@ -376,7 +390,9 @@ "//media/base/android:video_capture_jni_headers", ] allow_circular_includes_from = [ "//media/base/android" ] - } else { + } + + if (!is_android || media_use_ffmpeg) { sources += [ "filters/opus_audio_decoder.cc", "filters/opus_audio_decoder.h", @@ -518,6 +534,7 @@ public_deps = [ "//media/base", "//media/audio", + "//third_party/opus", ] deps += [ @@ -666,13 +683,20 @@ sources += [ "ffmpeg/ffmpeg_common_unittest.cc", "filters/audio_decoder_unittest.cc", - "filters/audio_file_reader_unittest.cc", - "filters/blocking_url_protocol_unittest.cc", "filters/ffmpeg_demuxer_unittest.cc", "filters/ffmpeg_glue_unittest.cc", - "filters/ffmpeg_video_decoder_unittest.cc", - "filters/in_memory_url_protocol_unittest.cc", ] + + # Even if FFmpeg is enabled we do not want these files on Android. + # TODO(watk): Refactor tests that could be made to run on Android. + if (!is_android) { + sources += [ + "filters/audio_file_reader_unittest.cc", + "filters/blocking_url_protocol_unittest.cc", + "filters/ffmpeg_video_decoder_unittest.cc", + "filters/in_memory_url_protocol_unittest.cc", + ] + } } if (media_use_libwebm) {
diff --git a/media/base/BUILD.gn b/media/base/BUILD.gn index 3565553..691e130 100644 --- a/media/base/BUILD.gn +++ b/media/base/BUILD.gn
@@ -220,13 +220,17 @@ if (media_use_ffmpeg) { sources += [ - "audio_video_metadata_extractor.cc", - "audio_video_metadata_extractor.h", "container_names.cc", "container_names.h", - "media_file_checker.cc", - "media_file_checker.h", ] + if (!is_android) { + sources += [ + "audio_video_metadata_extractor.cc", + "audio_video_metadata_extractor.h", + "media_file_checker.cc", + "media_file_checker.h", + ] + } deps += [ "//third_party/ffmpeg" ] } @@ -432,7 +436,9 @@ "//testing/gtest", ] - if (media_use_ffmpeg) { + # Even if FFmpeg is enabled on Android we don't want these. + # TODO(watk): Refactor tests that could be made to run on Android. + if (media_use_ffmpeg && !is_android) { sources += [ "audio_video_metadata_extractor_unittest.cc", "media_file_checker_unittest.cc",
diff --git a/media/blink/BUILD.gn b/media/blink/BUILD.gn index a805c42..eb0661b 100644 --- a/media/blink/BUILD.gn +++ b/media/blink/BUILD.gn
@@ -2,6 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//media/media_options.gni") import("//testing/test.gni") component("blink") { @@ -40,8 +41,6 @@ "cdm_result_promise_helper.h", "cdm_session_adapter.cc", "cdm_session_adapter.h", - "encrypted_media_player_support.cc", - "encrypted_media_player_support.h", "key_system_config_selector.cc", "key_system_config_selector.h", "new_session_cdm_result_promise.cc", @@ -63,8 +62,6 @@ "webinbandtexttrack_impl.cc", "webinbandtexttrack_impl.h", "webmediaplayer_delegate.h", - "webmediaplayer_impl.cc", - "webmediaplayer_impl.h", "webmediaplayer_params.cc", "webmediaplayer_params.h", "webmediaplayer_util.cc", @@ -75,8 +72,8 @@ "websourcebuffer_impl.h", ] - if (is_android) { - sources -= [ + if (media_use_ffmpeg || !is_android) { + sources += [ "encrypted_media_player_support.cc", "encrypted_media_player_support.h", "webmediaplayer_impl.cc",
diff --git a/media/cdm/ppapi/BUILD.gn b/media/cdm/ppapi/BUILD.gn index 1fdebd1..b6b2dec 100644 --- a/media/cdm/ppapi/BUILD.gn +++ b/media/cdm/ppapi/BUILD.gn
@@ -5,9 +5,7 @@ import("//build/config/features.gni") import("//chrome/version.gni") # TODO layering violation! import("//media/cdm/ppapi/cdm_adapter.gni") - -# Android doesn't use ffmpeg. -use_ffmpeg = !is_android +import("//media/media_options.gni") # The GYP version supports build flags "use_fake_video_decoder" and # "use_vpx". These should be added here if necessary but its not clear if @@ -36,7 +34,7 @@ "//url", ] - if (use_ffmpeg) { + if (media_use_ffmpeg) { sources += [ "external_clear_key/ffmpeg_cdm_audio_decoder.cc", "external_clear_key/ffmpeg_cdm_audio_decoder.h",
diff --git a/media/test/BUILD.gn b/media/test/BUILD.gn index b2b5002..c4f4d4d 100644 --- a/media/test/BUILD.gn +++ b/media/test/BUILD.gn
@@ -7,7 +7,9 @@ source_set("pipeline_integration_test_base") { testonly = true - if (media_use_ffmpeg) { + # Even if FFmpeg is enabled on Android we don't want these. + # TODO(watk): Refactor tests that could be made to run on Android. + if (media_use_ffmpeg && !is_android) { sources = [ "pipeline_integration_test_base.cc", "pipeline_integration_test_base.h", @@ -28,7 +30,7 @@ source_set("pipeline_integration_tests") { testonly = true - if (media_use_ffmpeg) { + if (media_use_ffmpeg && !is_android) { sources = [ "pipeline_integration_test.cc", ] @@ -56,7 +58,7 @@ source_set("pipeline_integration_perftests") { testonly = true - if (media_use_ffmpeg) { + if (media_use_ffmpeg && !is_android) { sources = [ "pipeline_integration_perftest.cc", ] @@ -79,7 +81,7 @@ source_set("mojo_pipeline_integration_tests") { testonly = true - if (media_use_ffmpeg) { + if (media_use_ffmpeg && !is_android) { sources = [ "pipeline_integration_test.cc", ]
diff --git a/mojo/converters/network/BUILD.gn b/mojo/converters/network/BUILD.gn new file mode 100644 index 0000000..17308b07 --- /dev/null +++ b/mojo/converters/network/BUILD.gn
@@ -0,0 +1,13 @@ +# 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. + +source_set("network") { + public_deps = [ + "//mojo/services/network/public/interfaces", + ] + sources = [ + "network_type_converters.cc", + "network_type_converters.h", + ] +}
diff --git a/mojo/converters/network/network_type_converters.cc b/mojo/converters/network/network_type_converters.cc new file mode 100644 index 0000000..94109da0 --- /dev/null +++ b/mojo/converters/network/network_type_converters.cc
@@ -0,0 +1,17 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "mojo/converters/network/network_type_converters.h" + +namespace mojo { + +// static +URLRequestPtr TypeConverter<URLRequestPtr, std::string>::Convert( + const std::string& input) { + URLRequestPtr result(URLRequest::New()); + result->url = input; + return result.Pass(); +} + +} // namespace mojo
diff --git a/mojo/converters/network/network_type_converters.h b/mojo/converters/network/network_type_converters.h new file mode 100644 index 0000000..4092cd7 --- /dev/null +++ b/mojo/converters/network/network_type_converters.h
@@ -0,0 +1,21 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MOJO_CONVERTERS_NETWORK_NETWORK_TYPE_CONVERTERS_H_ +#define MOJO_CONVERTERS_NETWORK_NETWORK_TYPE_CONVERTERS_H_ + +#include <string> + +#include "mojo/services/network/public/interfaces/url_loader.mojom.h" + +namespace mojo { + +template <> +struct TypeConverter<URLRequestPtr, std::string> { + static URLRequestPtr Convert(const std::string& input); +}; + +} // namespace mojo + +#endif // MOJO_CONVERTERS_NETWORK_NETWORK_TYPE_CONVERTERS_H_
diff --git a/mojo/services/network/public/interfaces/url_loader.mojom b/mojo/services/network/public/interfaces/url_loader.mojom index f960109..8a18c260 100644 --- a/mojo/services/network/public/interfaces/url_loader.mojom +++ b/mojo/services/network/public/interfaces/url_loader.mojom
@@ -35,6 +35,9 @@ // servers to also not satisfy the request from their cache. This has the // effect of forcing a full end-to-end fetch. bool bypass_cache = false; + + // The time when this request originated. 0 indicates that it is not recorded. + int64 originating_time_ticks = 0; }; struct URLResponse {
diff --git a/native_client_sdk/src/build_tools/build_sdk.py b/native_client_sdk/src/build_tools/build_sdk.py index e99216a..04a31606 100755 --- a/native_client_sdk/src/build_tools/build_sdk.py +++ b/native_client_sdk/src/build_tools/build_sdk.py
@@ -395,6 +395,9 @@ ['irt_core_newlib_x32.nexe', 'irt_core_x86_32.nexe'], ['irt_core_newlib_x64.nexe', 'irt_core_x86_64.nexe'], ] + arm_files = [ + ['elf_loader_newlib_arm.nexe', 'elf_loader_arm.nexe'], + ] tools_files_64 = [] @@ -429,19 +432,18 @@ pair[0] += '.exe' pair[1] += '.exe' - InstallFiles(GetNinjaOutDir('x64'), tools_dir, tools_files_64) - InstallFiles(GetNinjaOutDir('ia32'), tools_dir, tools_files_32) - # Add ARM binaries if platform == 'linux' and not options.no_arm_trusted: - arm_files = [ + arm_files += [ ['irt_core_newlib_arm.nexe', 'irt_core_arm.nexe'], - ['elf_loader_newlib_arm.nexe', 'elf_loader_arm.nexe'], ['nacl_helper_bootstrap', 'nacl_helper_bootstrap_arm'], ['nonsfi_loader_newlib_arm_nonsfi.nexe', 'nonsfi_loader_arm'], ['sel_ldr', 'sel_ldr_arm'] ] - InstallFiles(GetNinjaOutDir('arm'), tools_dir, arm_files) + + InstallFiles(GetNinjaOutDir('x64'), tools_dir, tools_files_64) + InstallFiles(GetNinjaOutDir('ia32'), tools_dir, tools_files_32) + InstallFiles(GetNinjaOutDir('arm'), tools_dir, arm_files) for tc in toolchains: if tc in ('host', 'clang-newlib'):
diff --git a/native_client_sdk/src/build_tools/json/naclsdk_manifest2.json b/native_client_sdk/src/build_tools/json/naclsdk_manifest2.json index e70bffa..88a8f663 100644 --- a/native_client_sdk/src/build_tools/json/naclsdk_manifest2.json +++ b/native_client_sdk/src/build_tools/json/naclsdk_manifest2.json
@@ -35,26 +35,6 @@ }, { "archives": [], - "description": "Chrome 39 bundle, revision xxxxx", - "name": "pepper_39", - "recommended": "no", - "repath": "pepper_39", - "revision": 0, - "stability": "post_stable", - "version": 39 - }, - { - "archives": [], - "description": "Chrome 40 bundle, revision xxxxx", - "name": "pepper_40", - "recommended": "no", - "repath": "pepper_40", - "revision": 0, - "stability": "post_stable", - "version": 40 - }, - { - "archives": [], "description": "Chrome 41 bundle, revision xxxxx", "name": "pepper_41", "recommended": "no", @@ -115,6 +95,16 @@ }, { "archives": [], + "description": "Chrome 47 bundle, revision xxxxx", + "name": "pepper_47", + "recommended": "no", + "repath": "pepper_47", + "revision": 0, + "stability": "post_stable", + "version": 47 + }, + { + "archives": [], "description": "Chrome Canary", "name": "pepper_canary", "recommended": "no",
diff --git a/native_client_sdk/src/build_tools/sdk_files.list b/native_client_sdk/src/build_tools/sdk_files.list index 4ed3cdf..a502a2f2 100644 --- a/native_client_sdk/src/build_tools/sdk_files.list +++ b/native_client_sdk/src/build_tools/sdk_files.list
@@ -455,7 +455,7 @@ tools/create_nmf.py tools/decode_dump.py [linux,mac]tools/dump_syms -[linux]tools/elf_loader_arm.nexe +tools/elf_loader_arm.nexe tools/fix_deps.py tools/fix_manifest.py tools/genhttpfs.py
diff --git a/native_client_sdk/src/build_tools/test_sdk.py b/native_client_sdk/src/build_tools/test_sdk.py index 355df28..b1cee6a 100755 --- a/native_client_sdk/src/build_tools/test_sdk.py +++ b/native_client_sdk/src/build_tools/test_sdk.py
@@ -128,9 +128,6 @@ for toolchain in ('clang-newlib', 'glibc', 'pnacl'): for arch in archs: - # TODO(sbc): Remove this once we get elf_loader.nexe added to the SDK - if toolchain == 'glibc' and arch == 'arm': - continue for config in configs: RunTest(location, toolchain, config, arch)
diff --git a/net/base/ip_address_number_unittest.cc b/net/base/ip_address_number_unittest.cc index 2ee7bed2..0b37bfa 100644 --- a/net/base/ip_address_number_unittest.cc +++ b/net/base/ip_address_number_unittest.cc
@@ -122,7 +122,7 @@ EXPECT_FALSE(IsIPv4Mapped(ipv4_number)); IPAddressNumber ipv6_number; - EXPECT_TRUE(ParseIPLiteralToNumber("::1", &ipv4_number)); + EXPECT_TRUE(ParseIPLiteralToNumber("::1", &ipv6_number)); EXPECT_FALSE(IsIPv4Mapped(ipv6_number)); IPAddressNumber ipv4mapped_number;
diff --git a/net/net.gypi b/net/net.gypi index 3ec18c02..79b1e2c 100644 --- a/net/net.gypi +++ b/net/net.gypi
@@ -333,6 +333,8 @@ 'quic/quic_flags.h', 'quic/quic_flow_controller.cc', 'quic/quic_flow_controller.h', + 'quic/quic_frame_list.cc', + 'quic/quic_frame_list.h', 'quic/quic_framer.cc', 'quic/quic_framer.h', 'quic/quic_packet_creator.cc',
diff --git a/net/quic/crypto/crypto_server_test.cc b/net/quic/crypto/crypto_server_test.cc index a905597..5bcbc70 100644 --- a/net/quic/crypto/crypto_server_test.cc +++ b/net/quic/crypto/crypto_server_test.cc
@@ -408,22 +408,18 @@ } } -// TODO(rtenneti): Enable the DefaultCert test after implementing ProofSource. -// See http://crbug.com/514472. TEST_P(CryptoServerTest, DefaultCert) { // Check that the server replies with a default certificate when no SNI is - // specified. + // specified. The CHLO is constructed to generate a REJ with certs, so must + // not contain a valid STK, and must include PDMD. // clang-format off CryptoHandshakeMessage msg = CryptoTestUtils::Message( "CHLO", "AEAD", "AESG", "KEXS", "C255", - "SCID", scid_hex_.c_str(), - "#004b5453", srct_hex_.c_str(), "PUBS", pub_hex_.c_str(), "NONC", nonce_hex_.c_str(), "PDMD", "X509", - "XLCT", XlctHexString().c_str(), "VER\0", client_version_string_.c_str(), "$padding", static_cast<int>(kClientHelloMinimumSize), nullptr); @@ -435,9 +431,15 @@ EXPECT_TRUE(out_.GetStringPiece(kPROF, &proof)); EXPECT_NE(0u, cert.size()); EXPECT_NE(0u, proof.size()); - const HandshakeFailureReason kRejectReasons[] = { - CLIENT_NONCE_INVALID_TIME_FAILURE}; - CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons)); + if (client_version_ <= QUIC_VERSION_26) { + const HandshakeFailureReason kRejectReasons[] = { + CLIENT_NONCE_INVALID_TIME_FAILURE}; + CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons)); + } else { + const HandshakeFailureReason kRejectReasons[] = { + SERVER_CONFIG_INCHOATE_HELLO_FAILURE}; + CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons)); + } } TEST_P(CryptoServerTest, TooSmall) { @@ -614,14 +616,23 @@ // clang-format on ShouldSucceed(msg); CheckRejectTag(); - const HandshakeFailureReason kRejectReasons[] = { - SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE, CLIENT_NONCE_INVALID_FAILURE, - SERVER_NONCE_DECRYPTION_FAILURE, + + if (client_version_ <= QUIC_VERSION_26) { + const HandshakeFailureReason kRejectReasons[] = { + SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE, CLIENT_NONCE_INVALID_FAILURE, + SERVER_NONCE_DECRYPTION_FAILURE}; + CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons)); + } else { + const HandshakeFailureReason kRejectReasons[] = { + SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE, CLIENT_NONCE_INVALID_FAILURE}; + CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons)); }; - CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons)); } TEST_P(CryptoServerTest, ReplayProtection) { + if (client_version_ > QUIC_VERSION_26) { + return; + } // This tests that disabling replay protection works. // clang-format off CryptoHandshakeMessage msg = CryptoTestUtils::Message(
diff --git a/net/quic/crypto/quic_crypto_server_config.cc b/net/quic/crypto/quic_crypto_server_config.cc index 8481a0e..5371438 100644 --- a/net/quic/crypto/quic_crypto_server_config.cc +++ b/net/quic/crypto/quic_crypto_server_config.cc
@@ -120,7 +120,6 @@ InsertStatus nonce_error) override { DVLOG(1) << "Using client nonce, unique: " << nonce_is_valid_and_unique << " nonce_error: " << nonce_error; - result_->info.unique = nonce_is_valid_and_unique; if (!nonce_is_valid_and_unique) { HandshakeFailureReason client_nonce_error; switch (nonce_error) { @@ -168,12 +167,7 @@ ClientHelloInfo::ClientHelloInfo(const IPAddressNumber& in_client_ip, QuicWallTime in_now) - : client_ip(in_client_ip), - now(in_now), - valid_source_address_token(false), - client_nonce_well_formed(false), - unique(false) { -} + : client_ip(in_client_ip), now(in_now), valid_source_address_token(false) {} ClientHelloInfo::~ClientHelloInfo() { } @@ -617,10 +611,7 @@ return QUIC_HANDSHAKE_FAILED; } - if (!info.valid_source_address_token || - !info.client_nonce_well_formed || - !info.unique || - !requested_config.get()) { + if (!info.reject_reasons.empty() || !requested_config.get()) { BuildRejection(*primary_config, client_hello, info, validate_chlo_result.cached_network_params, use_stateless_rejects, server_designated_connection_id, rand, @@ -1032,10 +1023,8 @@ } } - if (client_hello.GetStringPiece(kNONC, &info->client_nonce) && - info->client_nonce.size() == kNonceSize) { - info->client_nonce_well_formed = true; - } else { + if (!client_hello.GetStringPiece(kNONC, &info->client_nonce) || + info->client_nonce.size() != kNonceSize) { info->reject_reasons.push_back(CLIENT_NONCE_INVALID_FAILURE); // Invalid client nonce. DVLOG(1) << "Invalid client nonce."; @@ -1046,27 +1035,36 @@ found_error = true; } - if (!replay_protection_) { - if (!found_error) { - info->unique = true; + // Server nonce is optional, and used for key derivation if present. + client_hello.GetStringPiece(kServerNonceTag, &info->server_nonce); + + if (version > QUIC_VERSION_26) { + DVLOG(1) << "No 0-RTT replay protection in QUIC_VERSION_27 and higher."; + // If the server nonce is empty and we're requiring handshake confirmation + // for DoS reasons then we must reject the CHLO. + if (FLAGS_quic_require_handshake_confirmation && + info->server_nonce.empty()) { + info->reject_reasons.push_back(SERVER_NONCE_REQUIRED_FAILURE); } + helper.ValidationComplete(QUIC_NO_ERROR, ""); + return; + } + + if (!replay_protection_) { DVLOG(1) << "No replay protection."; helper.ValidationComplete(QUIC_NO_ERROR, ""); return; } - client_hello.GetStringPiece(kServerNonceTag, &info->server_nonce); if (!info->server_nonce.empty()) { // If the server nonce is present, use it to establish uniqueness. HandshakeFailureReason server_nonce_error = ValidateServerNonce(info->server_nonce, info->now); - if (server_nonce_error == HANDSHAKE_OK) { - info->unique = true; - } else { + bool is_unique = server_nonce_error == HANDSHAKE_OK; + if (!is_unique) { info->reject_reasons.push_back(server_nonce_error); - info->unique = false; } - DVLOG(1) << "Using server nonce, unique: " << info->unique; + DVLOG(1) << "Using server nonce, unique: " << is_unique; helper.ValidationComplete(QUIC_NO_ERROR, ""); return; }
diff --git a/net/quic/crypto/quic_crypto_server_config.h b/net/quic/crypto/quic_crypto_server_config.h index 4a5c83f..cb3f776 100644 --- a/net/quic/crypto/quic_crypto_server_config.h +++ b/net/quic/crypto/quic_crypto_server_config.h
@@ -50,8 +50,6 @@ // Outputs from EvaluateClientHello. bool valid_source_address_token; - bool client_nonce_well_formed; - bool unique; base::StringPiece sni; base::StringPiece client_nonce; base::StringPiece server_nonce; @@ -145,7 +143,9 @@ // into a KDF before use. In tests, use TESTING. // |server_nonce_entropy|: an entropy source used to generate the orbit and // key for server nonces, which are always local to a given instance of a - // server. + // server. Not owned. + // |proof_source|: provides certificate chains and signatures. This class + // takes ownership of |proof_source|. QuicCryptoServerConfig(base::StringPiece source_address_token_secret, QuicRandom* server_nonce_entropy); ~QuicCryptoServerConfig();
diff --git a/net/quic/quic_connection.cc b/net/quic/quic_connection.cc index f639eb7..74a262680 100644 --- a/net/quic/quic_connection.cc +++ b/net/quic/quic_connection.cc
@@ -1626,7 +1626,9 @@ OnWriteError(result.error_code); DLOG(ERROR) << ENDPOINT << "failed writing " << encrypted->length() << " bytes " - << " from host " << self_address().ToStringWithoutPort() + << " from host " << (self_address().address().empty() + ? " empty address " + : self_address().ToStringWithoutPort()) << " to address " << peer_address().ToString(); return false; } @@ -1763,7 +1765,7 @@ if (retransmission_alarm_->IsSet()) { return; } - packet_generator_.AddControlFrame(QuicFrame(new QuicPingFrame)); + packet_generator_.AddControlFrame(QuicFrame(QuicPingFrame())); } void QuicConnection::SendAck() {
diff --git a/net/quic/quic_connection_logger.cc b/net/quic/quic_connection_logger.cc index 9be77b9..956138f 100644 --- a/net/quic/quic_connection_logger.cc +++ b/net/quic/quic_connection_logger.cc
@@ -416,8 +416,7 @@ ++num_blocked_frames_sent_; net_log_.AddEvent( NetLog::TYPE_QUIC_SESSION_BLOCKED_FRAME_SENT, - base::Bind(&NetLogQuicBlockedFrameCallback, - frame.blocked_frame)); + base::Bind(&NetLogQuicBlockedFrameCallback, frame.blocked_frame)); break; case STOP_WAITING_FRAME: net_log_.AddEvent(
diff --git a/net/quic/quic_connection_test.cc b/net/quic/quic_connection_test.cc index f60c84e..306f496 100644 --- a/net/quic/quic_connection_test.cc +++ b/net/quic/quic_connection_test.cc
@@ -239,6 +239,7 @@ framer_(SupportedVersions(version_)), last_packet_size_(0), write_blocked_(false), + write_should_fail_(false), block_on_next_write_(false), is_write_blocked_data_buffered_(false), final_bytes_of_last_packet_(0), @@ -274,6 +275,11 @@ if (IsWriteBlocked()) { return WriteResult(WRITE_STATUS_BLOCKED, -1); } + + if (ShouldWriteFail()) { + return WriteResult(WRITE_STATUS_ERROR, 0); + } + last_packet_size_ = packet.length(); if (!write_pause_time_delta_.IsZero()) { @@ -286,10 +292,14 @@ return is_write_blocked_data_buffered_; } + bool ShouldWriteFail() { return write_should_fail_; } + bool IsWriteBlocked() const override { return write_blocked_; } void SetWritable() override { write_blocked_ = false; } + void SetShouldWriteFail() { write_should_fail_ = true; } + QuicByteCount GetMaxPacketSize( const IPEndPoint& /*peer_address*/) const override { return max_packet_size_; @@ -383,6 +393,7 @@ SimpleQuicFramer framer_; size_t last_packet_size_; bool write_blocked_; + bool write_should_fail_; bool block_on_next_write_; bool is_write_blocked_data_buffered_; uint32 final_bytes_of_last_packet_; @@ -1076,7 +1087,7 @@ QuicFrames frames; QuicPaddingFrame padding; frames.push_back(QuicFrame(&frame1_)); - frames.push_back(QuicFrame(&padding)); + frames.push_back(QuicFrame(padding)); scoped_ptr<QuicPacket> packet(ConstructPacket(header, frames)); char buffer[kMaxPacketSize]; scoped_ptr<QuicEncryptedPacket> encrypted(framer_.EncryptPayload( @@ -1107,7 +1118,7 @@ QuicFrames frames; QuicPaddingFrame padding; frames.push_back(QuicFrame(&frame1_)); - frames.push_back(QuicFrame(&padding)); + frames.push_back(QuicFrame(padding)); scoped_ptr<QuicPacket> packet(ConstructPacket(header, frames)); char buffer[kMaxPacketSize]; scoped_ptr<QuicEncryptedPacket> encrypted(framer_.EncryptPayload( @@ -3650,6 +3661,16 @@ EXPECT_EQ(0u, connection_.NumQueuedPackets()); } +TEST_P(QuicConnectionTest, FailToSendFirstPacket) { + // Test that the connection does not crash when it fails to send the first + // packet at which point self_address_ might be uninitialized. + EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(1); + QuicPacket* packet = ConstructDataPacket(1, 0, !kEntropyFlag); + writer_->SetShouldWriteFail(); + connection_.SendPacket(ENCRYPTION_NONE, 1, packet, kTestEntropyHash, + HAS_RETRANSMITTABLE_DATA, false, false); +} + TEST_P(QuicConnectionTest, SendSchedulerEAGAIN) { QuicPacket* packet = ConstructDataPacket(1, 0, !kEntropyFlag); BlockOnNextWrite();
diff --git a/net/quic/quic_crypto_server_stream_test.cc b/net/quic/quic_crypto_server_stream_test.cc index 5a999ed..88b6de2d 100644 --- a/net/quic/quic_crypto_server_stream_test.cc +++ b/net/quic/quic_crypto_server_stream_test.cc
@@ -141,6 +141,9 @@ } bool AsyncStrikeRegisterVerification() { + if (server_connection_->version() > QUIC_VERSION_26) { + return false; + } return GetParam(); }
diff --git a/net/quic/quic_flags.cc b/net/quic/quic_flags.cc index d3e5a40..3feb646 100644 --- a/net/quic/quic_flags.cc +++ b/net/quic/quic_flags.cc
@@ -51,7 +51,7 @@ // If true, require handshake confirmation for QUIC connections, functionally // disabling 0-rtt handshakes. -// TODO(rtenneti): Enable this flag after fixing tests. +// TODO(rtenneti): Enable this flag after CryptoServerTest's are fixed. bool FLAGS_quic_require_handshake_confirmation = false; // Disables special treatment of truncated acks, since older retransmissions are @@ -80,3 +80,8 @@ // If true, accounts for available (implicitly opened) streams under a separate // quota from open streams, which is 10 times larger. bool FLAGS_allow_many_available_streams = true; + +// If true, QuicPacketReader::ReadAndDispatchPackets will only return true if +// recvmmsg fills all of the passed in messages. Otherwise, it will return true +// if recvmmsg read any messages. +bool FLAGS_quic_read_packets_full_recvmmsg = true;
diff --git a/net/quic/quic_flags.h b/net/quic/quic_flags.h index e613ea6..bb66a23 100644 --- a/net/quic/quic_flags.h +++ b/net/quic/quic_flags.h
@@ -28,5 +28,6 @@ NET_EXPORT_PRIVATE extern bool FLAGS_quic_packet_queue_use_interval_set; NET_EXPORT_PRIVATE extern bool FLAGS_shift_quic_cubic_epoch_when_app_limited; NET_EXPORT_PRIVATE extern bool FLAGS_allow_many_available_streams; +NET_EXPORT_PRIVATE extern bool FLAGS_quic_read_packets_full_recvmmsg; #endif // NET_QUIC_QUIC_FLAGS_H_
diff --git a/net/quic/quic_frame_list.cc b/net/quic/quic_frame_list.cc new file mode 100644 index 0000000..a69c7c6 --- /dev/null +++ b/net/quic/quic_frame_list.cc
@@ -0,0 +1,198 @@ +// Copyright (c) 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/quic/quic_frame_list.h" + +#include "base/logging.h" + +namespace net { + +QuicFrameList::FrameData::FrameData(QuicStreamOffset offset, string segment) + : offset(offset), segment(segment) {} + +QuicFrameList::QuicFrameList() {} + +QuicFrameList::~QuicFrameList() { + Clear(); +} + +QuicErrorCode QuicFrameList::WriteAtOffset(QuicStreamOffset offset, + StringPiece data, + size_t* const bytes_written) { + *bytes_written = 0; + const size_t data_len = data.size(); + auto insertion_point = FindInsertionPoint(offset, data_len); + if (IsDuplicate(offset, data_len, insertion_point)) { + return QUIC_NO_ERROR; + } + + if (FrameOverlapsBufferedData(offset, data_len, insertion_point)) { + return QUIC_INVALID_STREAM_DATA; + } + + DVLOG(1) << "Buffering stream data at offset " << offset; + // Inserting an empty string and then copying to avoid the extra copy. + insertion_point = frame_list_.insert(insertion_point, FrameData(offset, "")); + data.CopyToString(&insertion_point->segment); + *bytes_written = data_len; + return QUIC_NO_ERROR; +} + +// Finds the place the frame should be inserted. If an identical frame is +// present, stops on the identical frame. +list<QuicFrameList::FrameData>::iterator QuicFrameList::FindInsertionPoint( + QuicStreamOffset offset, + size_t len) { + if (frame_list_.empty()) { + return frame_list_.begin(); + } + // If it's after all buffered_frames, return the end. + if (offset >= + (frame_list_.rbegin()->offset + frame_list_.rbegin()->segment.length())) { + return frame_list_.end(); + } + auto iter = frame_list_.begin(); + // Only advance the iterator if the data begins after the already received + // frame. If the new frame overlaps with an existing frame, the iterator will + // still point to the frame it overlaps with. + while (iter != frame_list_.end() && + offset >= iter->offset + iter->segment.length()) { + ++iter; + } + return iter; +} + +// Returns true if |frame| contains data which overlaps buffered data +// (indicating an invalid stream frame has been received). +bool QuicFrameList::FrameOverlapsBufferedData( + QuicStreamOffset offset, + size_t data_len, + list<FrameData>::const_iterator insertion_point) const { + if (frame_list_.empty() || insertion_point == frame_list_.end()) { + return false; + } + // If there is a buffered frame with a higher starting offset, then check to + // see if the new frame overlaps the beginning of the higher frame. + if (offset < insertion_point->offset && + offset + data_len > insertion_point->offset) { + DVLOG(1) << "New frame overlaps next frame: " << offset << " + " << data_len + << " > " << insertion_point->offset; + return true; + } + // If there is a buffered frame with a lower starting offset, then check to + // see if the buffered frame runs into the new frame. + if (offset >= insertion_point->offset && + offset < insertion_point->offset + insertion_point->segment.length()) { + DVLOG(1) << "Preceeding frame overlaps new frame: " + << insertion_point->offset << " + " + << insertion_point->segment.length() << " > " << offset; + return true; + } + + return false; +} + +// Returns true if the sequencer has received this frame before. +bool QuicFrameList::IsDuplicate( + QuicStreamOffset offset, + size_t data_len, + list<FrameData>::const_iterator insertion_point) const { + // A frame is duplicate if the frame offset is smaller than the bytes consumed + // or identical to an already received frame. + return offset < total_bytes_read_ || (insertion_point != frame_list_.end() && + offset == insertion_point->offset); +} + +int QuicFrameList::GetReadableRegions(struct iovec* iov, int iov_len) const { + list<FrameData>::const_iterator it = frame_list_.begin(); + int index = 0; + QuicStreamOffset offset = total_bytes_read_; + while (it != frame_list_.end() && index < iov_len) { + if (it->offset != offset) { + return index; + } + + iov[index].iov_base = + static_cast<void*>(const_cast<char*>(it->segment.data())); + iov[index].iov_len = it->segment.size(); + offset += it->segment.size(); + + ++index; + ++it; + } + return index; +} + +bool QuicFrameList::IncreaseTotalReadAndInvalidate(size_t bytes_used) { + size_t end_offset = total_bytes_read_ + bytes_used; + while (!frame_list_.empty() && end_offset != total_bytes_read_) { + list<FrameData>::iterator it = frame_list_.begin(); + if (it->offset != total_bytes_read_) { + return false; + } + + if (it->offset + it->segment.length() <= end_offset) { + total_bytes_read_ += it->segment.length(); + // This chunk is entirely consumed. + frame_list_.erase(it); + continue; + } + + // Partially consume this frame. + size_t delta = end_offset - it->offset; + total_bytes_read_ += delta; + string new_data = it->segment.substr(delta); + frame_list_.erase(it); + frame_list_.push_front(FrameData(total_bytes_read_, new_data)); + break; + } + return true; +} + +size_t QuicFrameList::ReadvAndInvalidate(const struct iovec* iov, + size_t iov_len) { + list<FrameData>::iterator it = frame_list_.begin(); + size_t iov_index = 0; + size_t iov_offset = 0; + size_t frame_offset = 0; + QuicStreamOffset initial_bytes_consumed = total_bytes_read_; + + while (iov_index < iov_len && it != frame_list_.end() && + it->offset == total_bytes_read_) { + int bytes_to_read = std::min(iov[iov_index].iov_len - iov_offset, + it->segment.size() - frame_offset); + + char* iov_ptr = static_cast<char*>(iov[iov_index].iov_base) + iov_offset; + memcpy(iov_ptr, it->segment.data() + frame_offset, bytes_to_read); + frame_offset += bytes_to_read; + iov_offset += bytes_to_read; + + if (iov[iov_index].iov_len == iov_offset) { + // We've filled this buffer. + iov_offset = 0; + ++iov_index; + } + if (it->segment.size() == frame_offset) { + // We've copied this whole frame + total_bytes_read_ += it->segment.size(); + frame_list_.erase(it); + it = frame_list_.begin(); + frame_offset = 0; + } + } + // Done copying. If there is a partial frame, update it. + if (frame_offset != 0) { + frame_list_.push_front( + FrameData(it->offset + frame_offset, it->segment.substr(frame_offset))); + frame_list_.erase(it); + total_bytes_read_ += frame_offset; + } + return total_bytes_read_ - initial_bytes_consumed; +} + +bool QuicFrameList::HasBytesToRead() const { + return !frame_list_.empty() && + frame_list_.begin()->offset == total_bytes_read_; +} +} // namespace net_quic
diff --git a/net/quic/quic_frame_list.h b/net/quic/quic_frame_list.h new file mode 100644 index 0000000..55ee804 --- /dev/null +++ b/net/quic/quic_frame_list.h
@@ -0,0 +1,99 @@ +// Copyright (c) 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef NET_QUIC_QUIC_FRAME_LIST_H_ +#define NET_QUIC_QUIC_FRAME_LIST_H_ + +#include "net/quic/quic_frame_list.h" +#include "net/quic/quic_protocol.h" + +using base::StringPiece; +using std::string; +using std::list; + +namespace net { + +namespace test { +class QuicStreamSequencerPeer; +} + +class NET_EXPORT_PRIVATE QuicFrameList { + public: + // A contiguous segment received by a QUIC stream. + struct FrameData { + FrameData(QuicStreamOffset offset, string segment); + + const QuicStreamOffset offset; + string segment; + }; + + explicit QuicFrameList(); + + ~QuicFrameList(); + + // Clear the buffer such that it is in its initial, newly constructed state. + void Clear() { frame_list_.clear(); } + + // Returns true if there is nothing to read in this buffer. + bool Empty() const { return frame_list_.empty(); } + + // Write the supplied data to this buffer. If the write was successful, + // return the number of bytes written in |bytes_written|. + // Return QUIC_INVALID_STREAM_DATA if |data| overlaps with existing data. + // No data will be written. + // Return QUIC_NO_ERROR, if |data| is duplicated with data written previously, + // and |bytes_written| = 0 + QuicErrorCode WriteAtOffset(QuicStreamOffset offset, + StringPiece data, + size_t* bytes_written); + + // Read from this buffer into given iovec array, upto number of iov_len iovec + // objects. + // Returns the number of bytes read into iov. + size_t ReadvAndInvalidate(const struct iovec* iov, size_t iov_len); + + // Returns the readable region of valid data in iovec format. The readable + // region is the buffer region where there is valid data not yet read by + // client. ReadAndInvalidate() and WriteAtOffset() change the readable region. + // The return value of this function is the number of iovec entries + // filled into in iov. If the region is empty, one iovec entry with 0 length + // is returned, and the function returns 0. If there are more readable + // regions than iov_size, the function only processes the first + // iov_size of them. + int GetReadableRegions(struct iovec* iov, int iov_len) const; + + // Called after GetReadableRegions() to accumulate total_bytes_read_ and free + // up block when all data in it have been read out. + // Pre-requisite: bytes_used <= ReadableBytes() + bool IncreaseTotalReadAndInvalidate(size_t bytes_used); + + // Whether there are bytes can be read out (offset == total_bytes_read_) + bool HasBytesToRead() const; + + size_t size() const { return frame_list_.size(); } + + QuicStreamOffset total_bytes_read() const { return total_bytes_read_; } + + private: + friend class test::QuicStreamSequencerPeer; + + list<FrameData>::iterator FindInsertionPoint(QuicStreamOffset offset, + size_t len); + + bool FrameOverlapsBufferedData( + QuicStreamOffset offset, + size_t data_len, + list<FrameData>::const_iterator insertion_point) const; + + bool IsDuplicate(QuicStreamOffset offset, + size_t data_len, + list<FrameData>::const_iterator insertion_point) const; + + list<FrameData> frame_list_; + QuicStreamOffset total_bytes_read_ = 0; +}; + +} // namespace net_quic + +#endif // NET_QUIC_QUIC_FRAME_LIST_H_
diff --git a/net/quic/quic_framer.cc b/net/quic/quic_framer.cc index a04824a0..9dd3d90 100644 --- a/net/quic/quic_framer.cc +++ b/net/quic/quic_framer.cc
@@ -268,7 +268,8 @@ InFecGroup is_in_fec_group, QuicPacketNumberLength packet_number_length) { // Prevent a rare crash reported in b/19458523. - if (frame.stream_frame == nullptr) { + if ((frame.type == STREAM_FRAME || frame.type == ACK_FRAME) && + frame.stream_frame == nullptr) { LOG(DFATAL) << "Cannot compute the length of a null frame. " << "type:" << frame.type << "free_bytes:" << free_bytes << " first_frame:" << first_frame
diff --git a/net/quic/quic_framer_test.cc b/net/quic/quic_framer_test.cc index 45710c1..5d3a7b7d 100644 --- a/net/quic/quic_framer_test.cc +++ b/net/quic/quic_framer_test.cc
@@ -2924,7 +2924,7 @@ QuicPaddingFrame padding_frame; QuicFrames frames; - frames.push_back(QuicFrame(&padding_frame)); + frames.push_back(QuicFrame(padding_frame)); // clang-format off unsigned char packet[kMaxPacketSize] = { @@ -2973,7 +2973,7 @@ QuicPaddingFrame padding_frame; QuicFrames frames; - frames.push_back(QuicFrame(&padding_frame)); + frames.push_back(QuicFrame(padding_frame)); // clang-format off unsigned char packet[kMaxPacketSize] = { @@ -3021,7 +3021,7 @@ QuicPaddingFrame padding_frame; QuicFrames frames; - frames.push_back(QuicFrame(&padding_frame)); + frames.push_back(QuicFrame(padding_frame)); // clang-format off unsigned char packet[kMaxPacketSize] = { @@ -3069,7 +3069,7 @@ QuicPaddingFrame padding_frame; QuicFrames frames; - frames.push_back(QuicFrame(&padding_frame)); + frames.push_back(QuicFrame(padding_frame)); // clang-format off unsigned char packet[kMaxPacketSize] = { @@ -3944,7 +3944,7 @@ QuicPingFrame ping_frame; QuicFrames frames; - frames.push_back(QuicFrame(&ping_frame)); + frames.push_back(QuicFrame(ping_frame)); // clang-format off unsigned char packet[] = { @@ -3986,7 +3986,7 @@ QuicMtuDiscoveryFrame mtu_discovery_frame; QuicFrames frames; - frames.push_back(QuicFrame(&mtu_discovery_frame)); + frames.push_back(QuicFrame(mtu_discovery_frame)); // clang-format off unsigned char packet[] = {
diff --git a/net/quic/quic_packet_creator.cc b/net/quic/quic_packet_creator.cc index 18a719a4..8e4f174 100644 --- a/net/quic/quic_packet_creator.cc +++ b/net/quic/quic_packet_creator.cc
@@ -451,7 +451,11 @@ bool possibly_truncated_by_length = packet_size_ == max_plaintext_size_ && queued_frames_.size() == 1 && queued_frames_.back().type == ACK_FRAME; - char buffer[kMaxPacketSize]; + // The optimized encryption algorithm implementations run faster when + // operating on aligned memory. + // TODO(rtenneti): Change the default 64 alignas value (used the default + // value from CACHELINE_SIZE). + ALIGNAS(64) char buffer[kMaxPacketSize]; scoped_ptr<QuicPacket> packet; // Use the packet_size_ instead of the buffer size to ensure smaller // packet sizes are properly used. @@ -638,8 +642,7 @@ return; } - QuicPaddingFrame padding; - bool success = AddFrame(QuicFrame(&padding), false, false, nullptr); + bool success = AddFrame(QuicFrame(QuicPaddingFrame()), false, false, nullptr); DCHECK(success); }
diff --git a/net/quic/quic_packet_creator_test.cc b/net/quic/quic_packet_creator_test.cc index c0565ed..4e73ba16 100644 --- a/net/quic/quic_packet_creator_test.cc +++ b/net/quic/quic_packet_creator_test.cc
@@ -1006,7 +1006,7 @@ EXPECT_TRUE(creator_.HasPendingFrames()); QuicPaddingFrame padding_frame; - EXPECT_TRUE(creator_.AddSavedFrame(QuicFrame(&padding_frame))); + EXPECT_TRUE(creator_.AddSavedFrame(QuicFrame(padding_frame))); EXPECT_TRUE(creator_.HasPendingFrames()); EXPECT_EQ(0u, creator_.BytesFree());
diff --git a/net/quic/quic_packet_generator.cc b/net/quic/quic_packet_generator.cc index eed8ec7d..a1a7dd2 100644 --- a/net/quic/quic_packet_generator.cc +++ b/net/quic/quic_packet_generator.cc
@@ -57,7 +57,8 @@ for (QuicFrame& frame : queued_control_frames_) { switch (frame.type) { case PADDING_FRAME: - delete frame.padding_frame; + case MTU_DISCOVERY_FRAME: + case PING_FRAME: break; case STREAM_FRAME: delete frame.stream_frame; @@ -65,9 +66,6 @@ case ACK_FRAME: delete frame.ack_frame; break; - case MTU_DISCOVERY_FRAME: - delete frame.mtu_discovery_frame; - break; case RST_STREAM_FRAME: delete frame.rst_stream_frame; break; @@ -86,9 +84,6 @@ case STOP_WAITING_FRAME: delete frame.stop_waiting_frame; break; - case PING_FRAME: - delete frame.ping_frame; - break; case NUM_FRAME_TYPES: DCHECK(false) << "Cannot delete type: " << frame.type; } @@ -250,7 +245,7 @@ // The MTU discovery frame is allocated on the stack, since it is going to be // serialized within this function. QuicMtuDiscoveryFrame mtu_discovery_frame; - QuicFrame frame(&mtu_discovery_frame); + QuicFrame frame(mtu_discovery_frame); // Send the probe packet with the new length. SetMaxPacketLength(target_mtu, /*force=*/true);
diff --git a/net/quic/quic_protocol.cc b/net/quic/quic_protocol.cc index d281358f..e04902f 100644 --- a/net/quic/quic_protocol.cc +++ b/net/quic/quic_protocol.cc
@@ -142,6 +142,8 @@ return MakeQuicTag('Q', '0', '2', '6'); case QUIC_VERSION_27: return MakeQuicTag('Q', '0', '2', '7'); + case QUIC_VERSION_28: + return MakeQuicTag('Q', '0', '2', '8'); default: // This shold be an ERROR because we should never attempt to convert an // invalid QuicVersion to be written to the wire. @@ -172,6 +174,7 @@ RETURN_STRING_LITERAL(QUIC_VERSION_25); RETURN_STRING_LITERAL(QUIC_VERSION_26); RETURN_STRING_LITERAL(QUIC_VERSION_27); + RETURN_STRING_LITERAL(QUIC_VERSION_28); default: return "QUIC_VERSION_UNSUPPORTED"; } @@ -263,59 +266,37 @@ QuicFrame::QuicFrame() {} -QuicFrame::QuicFrame(QuicPaddingFrame* padding_frame) - : type(PADDING_FRAME), - padding_frame(padding_frame) { -} +QuicFrame::QuicFrame(QuicPaddingFrame padding_frame) + : type(PADDING_FRAME), padding_frame(padding_frame) {} QuicFrame::QuicFrame(QuicStreamFrame* stream_frame) - : type(STREAM_FRAME), - stream_frame(stream_frame) { -} + : type(STREAM_FRAME), stream_frame(stream_frame) {} -QuicFrame::QuicFrame(QuicAckFrame* frame) - : type(ACK_FRAME), - ack_frame(frame) { -} +QuicFrame::QuicFrame(QuicAckFrame* frame) : type(ACK_FRAME), ack_frame(frame) {} -QuicFrame::QuicFrame(QuicMtuDiscoveryFrame* frame) - : type(MTU_DISCOVERY_FRAME), mtu_discovery_frame(frame) { -} +QuicFrame::QuicFrame(QuicMtuDiscoveryFrame frame) + : type(MTU_DISCOVERY_FRAME), mtu_discovery_frame(frame) {} QuicFrame::QuicFrame(QuicStopWaitingFrame* frame) - : type(STOP_WAITING_FRAME), - stop_waiting_frame(frame) { -} + : type(STOP_WAITING_FRAME), stop_waiting_frame(frame) {} -QuicFrame::QuicFrame(QuicPingFrame* frame) - : type(PING_FRAME), - ping_frame(frame) { -} +QuicFrame::QuicFrame(QuicPingFrame frame) + : type(PING_FRAME), ping_frame(frame) {} QuicFrame::QuicFrame(QuicRstStreamFrame* frame) - : type(RST_STREAM_FRAME), - rst_stream_frame(frame) { -} + : type(RST_STREAM_FRAME), rst_stream_frame(frame) {} QuicFrame::QuicFrame(QuicConnectionCloseFrame* frame) - : type(CONNECTION_CLOSE_FRAME), - connection_close_frame(frame) { -} + : type(CONNECTION_CLOSE_FRAME), connection_close_frame(frame) {} QuicFrame::QuicFrame(QuicGoAwayFrame* frame) - : type(GOAWAY_FRAME), - goaway_frame(frame) { -} + : type(GOAWAY_FRAME), goaway_frame(frame) {} QuicFrame::QuicFrame(QuicWindowUpdateFrame* frame) - : type(WINDOW_UPDATE_FRAME), - window_update_frame(frame) { -} + : type(WINDOW_UPDATE_FRAME), window_update_frame(frame) {} QuicFrame::QuicFrame(QuicBlockedFrame* frame) - : type(BLOCKED_FRAME), - blocked_frame(frame) { -} + : type(BLOCKED_FRAME), blocked_frame(frame) {} QuicFecData::QuicFecData() : fec_group(0) {} @@ -785,43 +766,39 @@ } RetransmittableFrames::~RetransmittableFrames() { - for (QuicFrames::iterator it = frames_.begin(); it != frames_.end(); ++it) { - switch (it->type) { + for (QuicFrame& frame : frames_) { + switch (frame.type) { + // Frames smaller than a pointer are inlined, so don't need to be deleted. case PADDING_FRAME: - delete it->padding_frame; + case MTU_DISCOVERY_FRAME: + case PING_FRAME: break; case STREAM_FRAME: - delete it->stream_frame; + delete frame.stream_frame; break; case ACK_FRAME: - delete it->ack_frame; - break; - case MTU_DISCOVERY_FRAME: - delete it->mtu_discovery_frame; + delete frame.ack_frame; break; case STOP_WAITING_FRAME: - delete it->stop_waiting_frame; - break; - case PING_FRAME: - delete it->ping_frame; + delete frame.stop_waiting_frame; break; case RST_STREAM_FRAME: - delete it->rst_stream_frame; + delete frame.rst_stream_frame; break; case CONNECTION_CLOSE_FRAME: - delete it->connection_close_frame; + delete frame.connection_close_frame; break; case GOAWAY_FRAME: - delete it->goaway_frame; + delete frame.goaway_frame; break; case WINDOW_UPDATE_FRAME: - delete it->window_update_frame; + delete frame.window_update_frame; break; case BLOCKED_FRAME: - delete it->blocked_frame; + delete frame.blocked_frame; break; case NUM_FRAME_TYPES: - DCHECK(false) << "Cannot delete type: " << it->type; + DCHECK(false) << "Cannot delete type: " << frame.type; } } // TODO(rtenneti): Delete the for loop once chrome has c++11 library support @@ -893,31 +870,31 @@ TransmissionInfo::TransmissionInfo() : retransmittable_frames(nullptr), packet_number_length(PACKET_1BYTE_PACKET_NUMBER), - sent_time(QuicTime::Zero()), bytes_sent(0), nack_count(0), + sent_time(QuicTime::Zero()), transmission_type(NOT_RETRANSMISSION), - all_transmissions(nullptr), in_flight(false), is_unackable(false), - is_fec_packet(false) {} + is_fec_packet(false), + all_transmissions(nullptr) {} TransmissionInfo::TransmissionInfo( RetransmittableFrames* retransmittable_frames, QuicPacketNumberLength packet_number_length, TransmissionType transmission_type, QuicTime sent_time, - QuicByteCount bytes_sent, + QuicPacketLength bytes_sent, bool is_fec_packet) : retransmittable_frames(retransmittable_frames), packet_number_length(packet_number_length), - sent_time(sent_time), bytes_sent(bytes_sent), nack_count(0), + sent_time(sent_time), transmission_type(transmission_type), - all_transmissions(nullptr), in_flight(false), is_unackable(false), - is_fec_packet(is_fec_packet) {} + is_fec_packet(is_fec_packet), + all_transmissions(nullptr) {} } // namespace net
diff --git a/net/quic/quic_protocol.h b/net/quic/quic_protocol.h index c942b8d..9d4ad54 100644 --- a/net/quic/quic_protocol.h +++ b/net/quic/quic_protocol.h
@@ -51,6 +51,7 @@ // TODO(rtenneti): Didn't use SpdyPriority because SpdyPriority is uint8 and // QuicPriority is uint32. Use SpdyPriority when we change the QUIC_VERSION. typedef uint32 QuicPriority; +typedef uint16 QuicPacketLength; // Default initial maximum size in bytes of a QUIC packet. const QuicByteCount kDefaultMaxPacketSize = 1350; @@ -346,6 +347,7 @@ // from QuicRstStreamFrame QUIC_VERSION_26 = 26, // In CHLO, send XLCT tag containing hash of leaf cert QUIC_VERSION_27 = 27, // Sends a nonce in the SHLO. + QUIC_VERSION_28 = 28, // Receiver can refuse to create a requested stream. }; // This vector contains QUIC versions which we currently support. @@ -356,7 +358,8 @@ // IMPORTANT: if you are adding to this list, follow the instructions at // http://sites/quic/adding-and-removing-versions static const QuicVersion kSupportedQuicVersions[] = { - QUIC_VERSION_27, QUIC_VERSION_26, QUIC_VERSION_25, QUIC_VERSION_24}; + QUIC_VERSION_28, QUIC_VERSION_27, QUIC_VERSION_26, QUIC_VERSION_25, + QUIC_VERSION_24}; typedef std::vector<QuicVersion> QuicVersionVector; @@ -436,6 +439,10 @@ // Closing stream locally, sending a RST to allow for proper flow control // accounting. Sent in response to a RST from the peer. QUIC_RST_ACKNOWLEDGEMENT, + // Receiver refused to create the stream (because its limit on open streams + // has been reached). The sender should retry the request later (using + // another stream). + QUIC_REFUSED_STREAM, // No error. Used as bound while iterating. QUIC_STREAM_LAST_ERROR, @@ -685,13 +692,11 @@ typedef QuicPacketPublicHeader QuicVersionNegotiationPacket; // A padding frame contains no payload. -struct NET_EXPORT_PRIVATE QuicPaddingFrame { -}; +struct NET_EXPORT_PRIVATE QuicPaddingFrame {}; // A ping frame contains no payload, though it is retransmittable, // and ACK'd just like other normal frames. -struct NET_EXPORT_PRIVATE QuicPingFrame { -}; +struct NET_EXPORT_PRIVATE QuicPingFrame {}; // A path MTU discovery frame contains no payload and is serialized as a ping // frame. @@ -994,15 +999,15 @@ struct NET_EXPORT_PRIVATE QuicFrame { QuicFrame(); - explicit QuicFrame(QuicPaddingFrame* padding_frame); + explicit QuicFrame(QuicPaddingFrame padding_frame); + explicit QuicFrame(QuicMtuDiscoveryFrame frame); + explicit QuicFrame(QuicPingFrame frame); + explicit QuicFrame(QuicStreamFrame* stream_frame); explicit QuicFrame(QuicAckFrame* frame); - explicit QuicFrame(QuicMtuDiscoveryFrame* frame); - explicit QuicFrame(QuicRstStreamFrame* frame); explicit QuicFrame(QuicConnectionCloseFrame* frame); explicit QuicFrame(QuicStopWaitingFrame* frame); - explicit QuicFrame(QuicPingFrame* frame); explicit QuicFrame(QuicGoAwayFrame* frame); explicit QuicFrame(QuicWindowUpdateFrame* frame); explicit QuicFrame(QuicBlockedFrame* frame); @@ -1012,14 +1017,15 @@ QuicFrameType type; union { - QuicPaddingFrame* padding_frame; + // Frames smaller than a pointer are inline. + QuicPaddingFrame padding_frame; + QuicMtuDiscoveryFrame mtu_discovery_frame; + QuicPingFrame ping_frame; + + // Frames larger than a pointer. QuicStreamFrame* stream_frame; QuicAckFrame* ack_frame; - QuicMtuDiscoveryFrame* mtu_discovery_frame; - QuicStopWaitingFrame* stop_waiting_frame; - - QuicPingFrame* ping_frame; QuicRstStreamFrame* rst_stream_frame; QuicConnectionCloseFrame* connection_close_frame; QuicGoAwayFrame* goaway_frame; @@ -1027,6 +1033,9 @@ QuicBlockedFrame* blocked_frame; }; }; +// QuicFrameType consumes 8 bytes with padding. +static_assert(sizeof(QuicFrame) <= 16, + "Frames larger than 8 bytes should be referenced by pointer."); typedef std::vector<QuicFrame> QuicFrames; @@ -1180,25 +1189,25 @@ QuicPacketNumberLength packet_number_length, TransmissionType transmission_type, QuicTime sent_time, - QuicByteCount bytes_sent, + QuicPacketLength bytes_sent, bool is_fec_packet); RetransmittableFrames* retransmittable_frames; QuicPacketNumberLength packet_number_length; + QuicPacketLength bytes_sent; + uint16 nack_count; QuicTime sent_time; - QuicByteCount bytes_sent; - QuicPacketCount nack_count; // Reason why this packet was transmitted. TransmissionType transmission_type; - // Stores the packet numbers of all transmissions of this packet. - // Must always be nullptr or have multiple elements. - PacketNumberList* all_transmissions; // In flight packets have not been abandoned or lost. bool in_flight; // True if the packet can never be acked, so it can be removed. bool is_unackable; // True if the packet is an FEC packet. bool is_fec_packet; + // Stores the packet numbers of all transmissions of this packet. + // Must always be nullptr or have multiple elements. + PacketNumberList* all_transmissions; }; // Convenience wrapper to wrap an iovec array and the total length, which must
diff --git a/net/quic/quic_protocol_test.cc b/net/quic/quic_protocol_test.cc index c74d3d1..fcadbe9 100644 --- a/net/quic/quic_protocol_test.cc +++ b/net/quic/quic_protocol_test.cc
@@ -14,7 +14,7 @@ namespace { TEST(QuicProtocolTest, AdjustErrorForVersion) { - ASSERT_EQ(8, QUIC_STREAM_LAST_ERROR) + ASSERT_EQ(9, QUIC_STREAM_LAST_ERROR) << "Any additions to QuicRstStreamErrorCode require an addition to " << "AdjustErrorForVersion and this associated test.";
diff --git a/net/quic/quic_session.cc b/net/quic/quic_session.cc index 7875bb86..12d19039 100644 --- a/net/quic/quic_session.cc +++ b/net/quic/quic_session.cc
@@ -679,7 +679,12 @@ // Check if the new number of open streams would cause the number of // open streams to exceed the limit. if (GetNumOpenStreams() >= get_max_open_streams()) { - CloseConnection(QUIC_TOO_MANY_OPEN_STREAMS); + if (connection()->version() <= QUIC_VERSION_27) { + CloseConnection(QUIC_TOO_MANY_OPEN_STREAMS); + } else { + // Refuse to open the stream. + SendRstStream(stream_id, QUIC_REFUSED_STREAM, 0); + } return nullptr; } }
diff --git a/net/quic/quic_stream_sequencer.cc b/net/quic/quic_stream_sequencer.cc index bd1bc6e..3989c4f9 100644 --- a/net/quic/quic_stream_sequencer.cc +++ b/net/quic/quic_stream_sequencer.cc
@@ -9,6 +9,7 @@ #include <utility> #include "base/logging.h" +#include "net/quic/quic_frame_list.h" #include "net/quic/reliable_quic_stream.h" using std::min; @@ -17,10 +18,6 @@ namespace net { -QuicStreamSequencer::FrameData::FrameData(QuicStreamOffset offset, - const string& segment) - : offset(offset), segment(segment) {} - QuicStreamSequencer::QuicStreamSequencer(ReliableQuicStream* quic_stream) : stream_(quic_stream), num_bytes_consumed_(0), @@ -29,27 +26,12 @@ num_bytes_buffered_(0), num_frames_received_(0), num_duplicate_frames_received_(0), - num_early_frames_received_(0) { -} + num_early_frames_received_(0) {} -QuicStreamSequencer::~QuicStreamSequencer() { -} +QuicStreamSequencer::~QuicStreamSequencer() {} void QuicStreamSequencer::OnStreamFrame(const QuicStreamFrame& frame) { ++num_frames_received_; - FrameList::iterator insertion_point = FindInsertionPoint(frame); - if (IsDuplicate(frame, insertion_point)) { - ++num_duplicate_frames_received_; - // Silently ignore duplicates. - return; - } - - if (FrameOverlapsBufferedData(frame, insertion_point)) { - stream_->CloseConnectionWithDetails( - QUIC_INVALID_STREAM_FRAME, "Stream frame overlaps with buffered data."); - return; - } - const QuicStreamOffset byte_offset = frame.offset; const size_t data_len = frame.data.length(); if (data_len == 0 && !frame.fin) { @@ -65,16 +47,25 @@ return; } } + size_t bytes_written; + QuicErrorCode result = + buffered_frames_.WriteAtOffset(byte_offset, frame.data, &bytes_written); + + if (result == QUIC_INVALID_STREAM_DATA) { + stream_->CloseConnectionWithDetails( + QUIC_INVALID_STREAM_FRAME, "Stream frame overlaps with buffered data."); + return; + } + if (result == QUIC_NO_ERROR && bytes_written == 0) { + ++num_duplicate_frames_received_; + // Silently ignore duplicates. + return; + } if (byte_offset > num_bytes_consumed_) { ++num_early_frames_received_; } - DVLOG(1) << "Buffering stream data at offset " << byte_offset; - // Inserting an empty string and then copying to avoid the extra copy. - insertion_point = - buffered_frames_.insert(insertion_point, FrameData(byte_offset, "")); - frame.data.CopyToString(&insertion_point->segment); num_bytes_buffered_ += data_len; if (blocked_) { @@ -103,13 +94,12 @@ bool QuicStreamSequencer::MaybeCloseStream() { if (!blocked_ && IsClosed()) { DVLOG(1) << "Passing up termination, as we've processed " - << num_bytes_consumed_ << " of " << close_offset_ - << " bytes."; + << num_bytes_consumed_ << " of " << close_offset_ << " bytes."; // This will cause the stream to consume the fin. // Technically it's an error if num_bytes_consumed isn't exactly // equal, but error handling seems silly at this point. stream_->OnDataAvailable(); - buffered_frames_.clear(); + buffered_frames_.Clear(); num_bytes_buffered_ = 0; return true; } @@ -118,163 +108,36 @@ int QuicStreamSequencer::GetReadableRegions(iovec* iov, size_t iov_len) const { DCHECK(!blocked_); - FrameList::const_iterator it = buffered_frames_.begin(); - size_t index = 0; - QuicStreamOffset offset = num_bytes_consumed_; - while (it != buffered_frames_.end() && index < iov_len) { - if (it->offset != offset) { - return index; - } - - iov[index].iov_base = - static_cast<void*>(const_cast<char*>(it->segment.data())); - iov[index].iov_len = it->segment.size(); - offset += it->segment.size(); - - ++index; - ++it; - } - return index; + return buffered_frames_.GetReadableRegions(iov, iov_len); } int QuicStreamSequencer::Readv(const struct iovec* iov, size_t iov_len) { DCHECK(!blocked_); - FrameList::iterator it = buffered_frames_.begin(); - size_t iov_index = 0; - size_t iov_offset = 0; - size_t frame_offset = 0; - QuicStreamOffset initial_bytes_consumed = num_bytes_consumed_; - - while (iov_index < iov_len && it != buffered_frames_.end() && - it->offset == num_bytes_consumed_) { - int bytes_to_read = min(iov[iov_index].iov_len - iov_offset, - it->segment.size() - frame_offset); - - char* iov_ptr = static_cast<char*>(iov[iov_index].iov_base) + iov_offset; - memcpy(iov_ptr, it->segment.data() + frame_offset, bytes_to_read); - frame_offset += bytes_to_read; - iov_offset += bytes_to_read; - - if (iov[iov_index].iov_len == iov_offset) { - // We've filled this buffer. - iov_offset = 0; - ++iov_index; - } - if (it->segment.size() == frame_offset) { - // We've copied this whole frame - RecordBytesConsumed(it->segment.size()); - buffered_frames_.erase(it); - it = buffered_frames_.begin(); - frame_offset = 0; - } - } - // Done copying. If there is a partial frame, update it. - if (frame_offset != 0) { - buffered_frames_.push_front( - FrameData(it->offset + frame_offset, it->segment.substr(frame_offset))); - buffered_frames_.erase(it); - RecordBytesConsumed(frame_offset); - } - return static_cast<int>(num_bytes_consumed_ - initial_bytes_consumed); + size_t bytes_read = buffered_frames_.ReadvAndInvalidate(iov, iov_len); + RecordBytesConsumed(bytes_read); + return static_cast<int>(bytes_read); } bool QuicStreamSequencer::HasBytesToRead() const { - return !buffered_frames_.empty() && - buffered_frames_.begin()->offset == num_bytes_consumed_; + return buffered_frames_.HasBytesToRead(); } bool QuicStreamSequencer::IsClosed() const { return num_bytes_consumed_ >= close_offset_; } -QuicStreamSequencer::FrameList::iterator -QuicStreamSequencer::FindInsertionPoint(const QuicStreamFrame& frame) { - if (buffered_frames_.empty()) { - return buffered_frames_.begin(); - } - // If it's after all buffered_frames, return the end. - if (frame.offset >= (buffered_frames_.rbegin()->offset + - buffered_frames_.rbegin()->segment.length())) { - return buffered_frames_.end(); - } - FrameList::iterator iter = buffered_frames_.begin(); - // Only advance the iterator if the data begins after the already received - // frame. If the new frame overlaps with an existing frame, the iterator will - // still point to the frame it overlaps with. - while (iter != buffered_frames_.end() && - frame.offset >= iter->offset + iter->segment.length()) { - ++iter; - } - return iter; -} - -bool QuicStreamSequencer::FrameOverlapsBufferedData( - const QuicStreamFrame& frame, - FrameList::const_iterator insertion_point) const { - if (buffered_frames_.empty() || insertion_point == buffered_frames_.end()) { - return false; - } - // If there is a buffered frame with a higher starting offset, then check to - // see if the new frame overlaps the beginning of the higher frame. - if (frame.offset < insertion_point->offset && - frame.offset + frame.data.length() > insertion_point->offset) { - DVLOG(1) << "New frame overlaps next frame: " << frame.offset << " + " - << frame.data.size() << " > " << insertion_point->offset; - return true; - } - // If there is a buffered frame with a lower starting offset, then check to - // see if the buffered frame runs into the new frame. - if (frame.offset >= insertion_point->offset && - frame.offset < - insertion_point->offset + insertion_point->segment.length()) { - DVLOG(1) << "Preceeding frame overlaps new frame: " - << insertion_point->offset << " + " - << insertion_point->segment.length() << " > " << frame.offset; - return true; - } - - return false; -} - void QuicStreamSequencer::MarkConsumed(size_t num_bytes_consumed) { DCHECK(!blocked_); - size_t end_offset = num_bytes_consumed_ + num_bytes_consumed; - while (!buffered_frames_.empty() && end_offset != num_bytes_consumed_) { - FrameList::iterator it = buffered_frames_.begin(); - if (it->offset != num_bytes_consumed_) { - LOG(DFATAL) << "Invalid argument to MarkConsumed. " - << " num_bytes_consumed_: " << num_bytes_consumed_ - << " end_offset: " << end_offset << " offset: " << it->offset - << " length: " << it->segment.length(); - stream_->Reset(QUIC_ERROR_PROCESSING_STREAM); - return; - } - - if (it->offset + it->segment.length() <= end_offset) { - RecordBytesConsumed(it->segment.length()); - // This chunk is entirely consumed. - buffered_frames_.erase(it); - continue; - } - - // Partially consume this frame. - size_t delta = end_offset - it->offset; - RecordBytesConsumed(delta); - string new_data = it->segment.substr(delta); - buffered_frames_.erase(it); - buffered_frames_.push_front(FrameData(num_bytes_consumed_, new_data)); - break; + bool result = + buffered_frames_.IncreaseTotalReadAndInvalidate(num_bytes_consumed); + if (!result) { + LOG(DFATAL) << "Invalid argument to MarkConsumed." + << " expect to consume: " << num_bytes_consumed + << ", but not enough bytes available."; + stream_->Reset(QUIC_ERROR_PROCESSING_STREAM); + return; } -} - -bool QuicStreamSequencer::IsDuplicate( - const QuicStreamFrame& frame, - FrameList::const_iterator insertion_point) const { - // A frame is duplicate if the frame offset is smaller than the bytes consumed - // or identical to an already received frame. - return frame.offset < num_bytes_consumed_ || - (insertion_point != buffered_frames_.end() && - frame.offset == insertion_point->offset); + RecordBytesConsumed(num_bytes_consumed); } void QuicStreamSequencer::SetBlockedUntilFlush() {
diff --git a/net/quic/quic_stream_sequencer.h b/net/quic/quic_stream_sequencer.h index 60a950b3..a1bdd32 100644 --- a/net/quic/quic_stream_sequencer.h +++ b/net/quic/quic_stream_sequencer.h
@@ -9,7 +9,7 @@ #include <string> #include "base/basictypes.h" -#include "net/base/iovec.h" +#include "net/quic/quic_frame_list.h" #include "net/quic/quic_protocol.h" namespace net { @@ -25,19 +25,6 @@ // up to the next layer. class NET_EXPORT_PRIVATE QuicStreamSequencer { public: - // A contiguous segment received by a QUIC stream. - struct FrameData { - FrameData(QuicStreamOffset offset, const std::string& segment); - - const QuicStreamOffset offset; - std::string segment; - }; - - // TODO(alyssar) use something better than strings. - // Maybe write new frames into a ring buffer, and keep track of consumed - // bytes, and gaps. - typedef std::list<FrameData> FrameList; - explicit QuicStreamSequencer(ReliableQuicStream* quic_stream); virtual ~QuicStreamSequencer(); @@ -93,20 +80,6 @@ private: friend class test::QuicStreamSequencerPeer; - // Finds the place the frame should be inserted. If an identical frame is - // present, stops on the identical frame. - FrameList::iterator FindInsertionPoint(const QuicStreamFrame& frame); - - // Returns true if |frame| contains data which overlaps buffered data - // (indicating an invalid stream frame has been received). - bool FrameOverlapsBufferedData( - const QuicStreamFrame& frame, - FrameList::const_iterator insertion_point) const; - - // Returns true if the sequencer has received this frame before. - bool IsDuplicate(const QuicStreamFrame& frame, - FrameList::const_iterator insertion_point) const; - // Wait until we've seen 'offset' bytes, and then terminate the stream. void CloseStreamAtOffset(QuicStreamOffset offset); @@ -125,7 +98,7 @@ QuicStreamOffset num_bytes_consumed_; // Stores buffered frames in offset order. - FrameList buffered_frames_; + QuicFrameList buffered_frames_; // The offset, if any, we got a stream termination for. When this many bytes // have been processed, the sequencer will be closed.
diff --git a/net/quic/quic_stream_sequencer_test.cc b/net/quic/quic_stream_sequencer_test.cc index 994ce84..a91929b 100644 --- a/net/quic/quic_stream_sequencer_test.cc +++ b/net/quic/quic_stream_sequencer_test.cc
@@ -523,8 +523,8 @@ // stream to be closed. EXPECT_CALL(stream_, Reset(QUIC_ERROR_PROCESSING_STREAM)); EXPECT_DFATAL(sequencer_->MarkConsumed(4), - "Invalid argument to MarkConsumed. num_bytes_consumed_: 3 " - "end_offset: 4 offset: 9 length: 17"); + "Invalid argument to MarkConsumed." + " expect to consume: 4, but not enough bytes available."); } TEST_F(QuicStreamSequencerTest, MarkConsumedWithMissingPacket) {
diff --git a/net/quic/quic_unacked_packet_map.cc b/net/quic/quic_unacked_packet_map.cc index 71088ae..bbe7b3f 100644 --- a/net/quic/quic_unacked_packet_map.cc +++ b/net/quic/quic_unacked_packet_map.cc
@@ -185,7 +185,7 @@ } void QuicUnackedPacketMap::NackPacket(QuicPacketNumber packet_number, - QuicPacketCount min_nacks) { + uint16 min_nacks) { DCHECK_GE(packet_number, least_unacked_); DCHECK_LT(packet_number, least_unacked_ + unacked_packets_.size()); unacked_packets_[packet_number - least_unacked_].nack_count = max(
diff --git a/net/quic/quic_unacked_packet_map.h b/net/quic/quic_unacked_packet_map.h index 1926d31..358491d 100644 --- a/net/quic/quic_unacked_packet_map.h +++ b/net/quic/quic_unacked_packet_map.h
@@ -42,7 +42,7 @@ bool IsUnacked(QuicPacketNumber packet_number) const; // Sets the nack count to the max of the current nack count and |min_nacks|. - void NackPacket(QuicPacketNumber packet_number, QuicPacketCount min_nacks); + void NackPacket(QuicPacketNumber packet_number, uint16 min_nacks); // Marks |packet_number| as no longer in flight. void RemoveFromInFlight(QuicPacketNumber packet_number);
diff --git a/net/quic/quic_utils.cc b/net/quic/quic_utils.cc index 641818e..b336202 100644 --- a/net/quic/quic_utils.cc +++ b/net/quic/quic_utils.cc
@@ -146,6 +146,7 @@ RETURN_STRING_LITERAL(QUIC_STREAM_PEER_GOING_AWAY); RETURN_STRING_LITERAL(QUIC_STREAM_CANCELLED); RETURN_STRING_LITERAL(QUIC_RST_ACKNOWLEDGEMENT); + RETURN_STRING_LITERAL(QUIC_REFUSED_STREAM); RETURN_STRING_LITERAL(QUIC_STREAM_LAST_ERROR); } // Return a default value so that we return this when |error| doesn't match
diff --git a/net/quic/test_tools/crypto_test_utils_chromium.cc b/net/quic/test_tools/crypto_test_utils_chromium.cc index 366dd5e2..ffa1788 100644 --- a/net/quic/test_tools/crypto_test_utils_chromium.cc +++ b/net/quic/test_tools/crypto_test_utils_chromium.cc
@@ -116,7 +116,7 @@ ProofSourceChromium* source = new ProofSourceChromium(); base::FilePath certs_dir = GetTestCertsDirectory(); CHECK(source->Initialize( - certs_dir.AppendASCII("quic_chain.crt"), + certs_dir.AppendASCII("quic_test.example.com.crt"), certs_dir.AppendASCII("quic_test.example.com.key.pkcs8"))); return source; }
diff --git a/net/quic/test_tools/quic_stream_sequencer_peer.cc b/net/quic/test_tools/quic_stream_sequencer_peer.cc index 591a2e9e..0d2c61b 100644 --- a/net/quic/test_tools/quic_stream_sequencer_peer.cc +++ b/net/quic/test_tools/quic_stream_sequencer_peer.cc
@@ -22,9 +22,11 @@ bool QuicStreamSequencerPeer::FrameOverlapsBufferedData( QuicStreamSequencer* sequencer, const QuicStreamFrame& frame) { - QuicStreamSequencer::FrameList::iterator it = - sequencer->FindInsertionPoint(frame); - return sequencer->FrameOverlapsBufferedData(frame, it); + list<QuicFrameList::FrameData>::iterator it = + sequencer->buffered_frames_.FindInsertionPoint(frame.offset, + frame.data.length()); + return sequencer->buffered_frames_.FrameOverlapsBufferedData( + frame.offset, frame.data.length(), it); } // static
diff --git a/net/socket/ssl_client_socket.cc b/net/socket/ssl_client_socket.cc index 3472fd0..cf8f40a 100644 --- a/net/socket/ssl_client_socket.cc +++ b/net/socket/ssl_client_socket.cc
@@ -127,14 +127,13 @@ void SSLClientSocket::RecordChannelIDSupport( ChannelIDService* channel_id_service, bool negotiated_channel_id, - bool channel_id_enabled, - bool supports_ecc) { + bool channel_id_enabled) { // Since this enum is used for a histogram, do not change or re-use values. enum { DISABLED = 0, CLIENT_ONLY = 1, CLIENT_AND_SERVER = 2, - CLIENT_NO_ECC = 3, + // CLIENT_NO_ECC is unused now. // CLIENT_BAD_SYSTEM_TIME is unused now. CLIENT_BAD_SYSTEM_TIME = 4, CLIENT_NO_CHANNEL_ID_SERVICE = 5, @@ -145,8 +144,6 @@ } else if (channel_id_enabled) { if (!channel_id_service) supported = CLIENT_NO_CHANNEL_ID_SERVICE; - else if (!supports_ecc) - supported = CLIENT_NO_ECC; else supported = CLIENT_ONLY; } @@ -164,10 +161,6 @@ DVLOG(1) << "NULL channel_id_service_, not enabling channel ID."; return false; } - if (!crypto::ECPrivateKey::IsSupported()) { - DVLOG(1) << "Elliptic Curve not supported, not enabling channel ID."; - return false; - } return true; }
diff --git a/net/socket/ssl_client_socket.h b/net/socket/ssl_client_socket.h index 1d38048d0..e3df669 100644 --- a/net/socket/ssl_client_socket.h +++ b/net/socket/ssl_client_socket.h
@@ -152,11 +152,9 @@ // Records histograms for channel id support during full handshakes - resumed // handshakes are ignored. - static void RecordChannelIDSupport( - ChannelIDService* channel_id_service, - bool negotiated_channel_id, - bool channel_id_enabled, - bool supports_ecc); + static void RecordChannelIDSupport(ChannelIDService* channel_id_service, + bool negotiated_channel_id, + bool channel_id_enabled); // Returns whether TLS channel ID is enabled. static bool IsChannelIDEnabled(
diff --git a/net/socket/ssl_client_socket_nss.cc b/net/socket/ssl_client_socket_nss.cc index 9f3aff6..29d8394 100644 --- a/net/socket/ssl_client_socket_nss.cc +++ b/net/socket/ssl_client_socket_nss.cc
@@ -648,10 +648,8 @@ void OnNSSBufferUpdated(int amount_in_read_buffer); void DidNSSRead(int result); void DidNSSWrite(int result); - void RecordChannelIDSupportOnNetworkTaskRunner( - bool negotiated_channel_id, - bool channel_id_enabled, - bool supports_ecc) const; + void RecordChannelIDSupportOnNetworkTaskRunner(bool negotiated_channel_id, + bool channel_id_enabled) const; //////////////////////////////////////////////////////////////////////////// // Methods that are called on both the network task runner and the NSS @@ -2131,23 +2129,17 @@ // network task runner state. PostOrRunCallback( FROM_HERE, - base::Bind(&Core::RecordChannelIDSupportOnNetworkTaskRunner, - this, - channel_id_xtn_negotiated_, - ssl_config_.channel_id_enabled, - crypto::ECPrivateKey::IsSupported())); + base::Bind(&Core::RecordChannelIDSupportOnNetworkTaskRunner, this, + channel_id_xtn_negotiated_, ssl_config_.channel_id_enabled)); } void SSLClientSocketNSS::Core::RecordChannelIDSupportOnNetworkTaskRunner( bool negotiated_channel_id, - bool channel_id_enabled, - bool supports_ecc) const { + bool channel_id_enabled) const { DCHECK(OnNetworkTaskRunner()); - RecordChannelIDSupport(channel_id_service_, - negotiated_channel_id, - channel_id_enabled, - supports_ecc); + RecordChannelIDSupport(channel_id_service_, negotiated_channel_id, + channel_id_enabled); } int SSLClientSocketNSS::Core::DoBufferRecv(IOBuffer* read_buffer, int len) {
diff --git a/net/socket/ssl_client_socket_openssl.cc b/net/socket/ssl_client_socket_openssl.cc index 92bf8f0..d575259 100644 --- a/net/socket/ssl_client_socket_openssl.cc +++ b/net/socket/ssl_client_socket_openssl.cc
@@ -1116,8 +1116,7 @@ RecordNegotiationExtension(); RecordChannelIDSupport(channel_id_service_, channel_id_sent_, - ssl_config_.channel_id_enabled, - crypto::ECPrivateKey::IsSupported()); + ssl_config_.channel_id_enabled); // Only record OCSP histograms if OCSP was requested. if (ssl_config_.signed_cert_timestamps_enabled ||
diff --git a/net/tools/quic/end_to_end_test.cc b/net/tools/quic/end_to_end_test.cc index 9f4ccaaa..dd13bcb6 100644 --- a/net/tools/quic/end_to_end_test.cc +++ b/net/tools/quic/end_to_end_test.cc
@@ -1100,9 +1100,15 @@ } client_->WaitForResponse(); - EXPECT_FALSE(client_->connected()); - EXPECT_EQ(QUIC_STREAM_CONNECTION_ERROR, client_->stream_error()); - EXPECT_EQ(QUIC_TOO_MANY_OPEN_STREAMS, client_->connection_error()); + if (negotiated_version_ <= QUIC_VERSION_27) { + EXPECT_FALSE(client_->connected()); + EXPECT_EQ(QUIC_STREAM_CONNECTION_ERROR, client_->stream_error()); + EXPECT_EQ(QUIC_TOO_MANY_OPEN_STREAMS, client_->connection_error()); + } else { + EXPECT_TRUE(client_->connected()); + EXPECT_EQ(QUIC_REFUSED_STREAM, client_->stream_error()); + EXPECT_EQ(QUIC_NO_ERROR, client_->connection_error()); + } } TEST_P(EndToEndTest, NegotiateCongestionControl) {
diff --git a/net/tools/quic/quic_dispatcher.cc b/net/tools/quic/quic_dispatcher.cc index 0a103ac6..31cc8e36 100644 --- a/net/tools/quic/quic_dispatcher.cc +++ b/net/tools/quic/quic_dispatcher.cc
@@ -487,7 +487,7 @@ time_wait_list_writer_.reset( packet_writer_factory_->Create(writer_.get(), nullptr)); return new QuicTimeWaitListManager(time_wait_list_writer_.get(), this, - helper_.get(), supported_versions()); + helper_.get()); } bool QuicDispatcher::HandlePacketForTimeWait(
diff --git a/net/tools/quic/quic_packet_reader.cc b/net/tools/quic/quic_packet_reader.cc index 1982269..1f368a6 100644 --- a/net/tools/quic/quic_packet_reader.cc +++ b/net/tools/quic/quic_packet_reader.cc
@@ -14,6 +14,7 @@ #include "base/logging.h" #include "net/base/ip_endpoint.h" +#include "net/quic/quic_flags.h" #include "net/tools/quic/quic_dispatcher.h" #include "net/tools/quic/quic_socket_utils.h" @@ -103,7 +104,12 @@ packets_dropped); } - return true; + if (FLAGS_quic_read_packets_full_recvmmsg) { + // We may not have read all of the packets available on the socket. + return packets_read == kNumPacketsPerReadMmsgCall; + } else { + return true; + } #else LOG(FATAL) << "Unsupported"; return false;
diff --git a/net/tools/quic/quic_packet_reader.h b/net/tools/quic/quic_packet_reader.h index 479fc6d..e667d59 100644 --- a/net/tools/quic/quic_packet_reader.h +++ b/net/tools/quic/quic_packet_reader.h
@@ -37,8 +37,8 @@ virtual ~QuicPacketReader(); // Reads a number of packets from the given fd, and then passes them off to - // the PacketProcessInterface. Returns true if at least 1 packet is read, - // false otherwise. + // the PacketProcessInterface. Returns true if there may be additional + // packets available on the socket. // Populates |packets_dropped| if it is non-null and the socket is configured // to track dropped packets and some packets are read. virtual bool ReadAndDispatchPackets(int fd,
diff --git a/net/tools/quic/quic_server.cc b/net/tools/quic/quic_server.cc index 392963d2..e0cd873d 100644 --- a/net/tools/quic/quic_server.cc +++ b/net/tools/quic/quic_server.cc
@@ -47,17 +47,7 @@ } // namespace -QuicServer::QuicServer() - : port_(0), - fd_(-1), - packets_dropped_(0), - overflow_supported_(false), - use_recvmmsg_(false), - crypto_config_(kSourceAddressTokenSecret, QuicRandom::GetInstance()), - supported_versions_(QuicSupportedVersions()), - packet_reader_(new QuicPacketReader()) { - Initialize(); -} +QuicServer::QuicServer() : QuicServer(QuicConfig(), QuicSupportedVersions()) {} QuicServer::QuicServer(const QuicConfig& config, const QuicVersionVector& supported_versions) @@ -215,14 +205,14 @@ if (event->in_events & EPOLLIN) { DVLOG(1) << "EPOLLIN"; - bool read = true; - while (read) { + bool more_to_read = true; + while (more_to_read) { if (use_recvmmsg_) { - read = packet_reader_->ReadAndDispatchPackets( + more_to_read = packet_reader_->ReadAndDispatchPackets( fd_, port_, dispatcher_.get(), overflow_supported_ ? &packets_dropped_ : nullptr); } else { - read = QuicPacketReader::ReadAndDispatchSinglePacket( + more_to_read = QuicPacketReader::ReadAndDispatchSinglePacket( fd_, port_, dispatcher_.get(), overflow_supported_ ? &packets_dropped_ : nullptr); }
diff --git a/net/tools/quic/quic_server_session_test.cc b/net/tools/quic/quic_server_session_test.cc index 7123496..d24b8378b 100644 --- a/net/tools/quic/quic_server_session_test.cc +++ b/net/tools/quic/quic_server_session_test.cc
@@ -189,9 +189,9 @@ } TEST_P(QuicServerSessionTest, MaxOpenStreams) { - // Test that the server closes the connection if a client attempts to open too - // many data streams. The server accepts slightly more than the negotiated - // stream limit to deal with rare cases where a client FIN/RST is lost. + // Test that the server refuses if a client attempts to open too many data + // streams. The server accepts slightly more than the negotiated stream limit + // to deal with rare cases where a client FIN/RST is lost. // The slightly increased stream limit is set during config negotiation. It // is either an increase of 10 over negotiated limit, or a fixed percentage @@ -220,8 +220,14 @@ // Now violate the server's internal stream limit. stream_id += 2; - EXPECT_CALL(*connection_, SendConnectionClose(QUIC_TOO_MANY_OPEN_STREAMS)); - EXPECT_CALL(*connection_, SendRstStream(_, _, _)).Times(0); + if (connection_->version() <= QUIC_VERSION_27) { + EXPECT_CALL(*connection_, SendConnectionClose(QUIC_TOO_MANY_OPEN_STREAMS)); + EXPECT_CALL(*connection_, SendRstStream(_, _, _)).Times(0); + } else { + EXPECT_CALL(*connection_, SendConnectionClose(_)).Times(0); + EXPECT_CALL(*connection_, SendRstStream(stream_id, QUIC_REFUSED_STREAM, 0)); + } + // Even if the connection remains open, the stream creation should fail. EXPECT_FALSE(QuicServerSessionPeer::GetIncomingDynamicStream(session_.get(), stream_id)); }
diff --git a/net/tools/quic/quic_time_wait_list_manager.cc b/net/tools/quic/quic_time_wait_list_manager.cc index 68d1b9e..1e433e5 100644 --- a/net/tools/quic/quic_time_wait_list_manager.cc +++ b/net/tools/quic/quic_time_wait_list_manager.cc
@@ -80,8 +80,7 @@ QuicTimeWaitListManager::QuicTimeWaitListManager( QuicPacketWriter* writer, QuicServerSessionVisitor* visitor, - QuicConnectionHelperInterface* helper, - const QuicVersionVector& supported_versions) + QuicConnectionHelperInterface* helper) : time_wait_period_( QuicTime::Delta::FromSeconds(FLAGS_quic_time_wait_list_seconds)), connection_id_clean_up_alarm_(
diff --git a/net/tools/quic/quic_time_wait_list_manager.h b/net/tools/quic/quic_time_wait_list_manager.h index 9a9eccd5..092f116 100644 --- a/net/tools/quic/quic_time_wait_list_manager.h +++ b/net/tools/quic/quic_time_wait_list_manager.h
@@ -44,8 +44,7 @@ // helper - used to run clean up alarms. (Owned by the dispatcher) QuicTimeWaitListManager(QuicPacketWriter* writer, QuicServerSessionVisitor* visitor, - QuicConnectionHelperInterface* helper, - const QuicVersionVector& supported_versions); + QuicConnectionHelperInterface* helper); ~QuicTimeWaitListManager() override; // Adds the given connection_id to time wait state for time_wait_period_.
diff --git a/net/tools/quic/quic_time_wait_list_manager_test.cc b/net/tools/quic/quic_time_wait_list_manager_test.cc index e6baf7d..8f5fd89 100644 --- a/net/tools/quic/quic_time_wait_list_manager_test.cc +++ b/net/tools/quic/quic_time_wait_list_manager_test.cc
@@ -96,10 +96,7 @@ protected: QuicTimeWaitListManagerTest() : helper_(&epoll_server_), - time_wait_list_manager_(&writer_, - &visitor_, - &helper_, - QuicSupportedVersions()), + time_wait_list_manager_(&writer_, &visitor_, &helper_), framer_(QuicSupportedVersions(), QuicTime::Zero(), Perspective::IS_SERVER),
diff --git a/net/tools/quic/test_tools/mock_quic_time_wait_list_manager.cc b/net/tools/quic/test_tools/mock_quic_time_wait_list_manager.cc index 7801db5..8e972f3 100644 --- a/net/tools/quic/test_tools/mock_quic_time_wait_list_manager.cc +++ b/net/tools/quic/test_tools/mock_quic_time_wait_list_manager.cc
@@ -16,10 +16,7 @@ QuicPacketWriter* writer, QuicServerSessionVisitor* visitor, QuicConnectionHelperInterface* helper) - : QuicTimeWaitListManager(writer, - visitor, - helper, - QuicSupportedVersions()) { + : QuicTimeWaitListManager(writer, visitor, helper) { // Though AddConnectionIdToTimeWait is mocked, we want to retain its // functionality. EXPECT_CALL(*this, AddConnectionIdToTimeWait(_, _, _, _))
diff --git a/net/tools/quic/test_tools/quic_test_client.cc b/net/tools/quic/test_tools/quic_test_client.cc index 718f0cf..708b4f8 100644 --- a/net/tools/quic/test_tools/quic_test_client.cc +++ b/net/tools/quic/test_tools/quic_test_client.cc
@@ -109,12 +109,11 @@ const QuicServerId& server_id, const QuicVersionVector& supported_versions, EpollServer* epoll_server) - : QuicClient(server_address, - server_id, - supported_versions, - epoll_server), - override_connection_id_(0), - test_writer_(nullptr) {} + : MockableQuicClient(server_address, + server_id, + QuicConfig(), + supported_versions, + epoll_server) {} MockableQuicClient::MockableQuicClient( IPEndPoint server_address, @@ -164,36 +163,29 @@ const string& server_hostname, bool secure, const QuicVersionVector& supported_versions) + : QuicTestClient(server_address, + server_hostname, + secure, + QuicConfig(), + supported_versions) {} + +QuicTestClient::QuicTestClient(IPEndPoint server_address, + const string& server_hostname, + bool secure, + const QuicConfig& config, + const QuicVersionVector& supported_versions) : client_(new MockableQuicClient(server_address, QuicServerId(server_hostname, server_address.port(), secure, PRIVACY_MODE_DISABLED), + config, supported_versions, &epoll_server_)) { Initialize(secure); } -QuicTestClient::QuicTestClient( - IPEndPoint server_address, - const string& server_hostname, - bool secure, - const QuicConfig& config, - const QuicVersionVector& supported_versions) - : client_( - new MockableQuicClient(server_address, - QuicServerId(server_hostname, - server_address.port(), - secure, - PRIVACY_MODE_DISABLED), - config, - supported_versions, - &epoll_server_)) { - Initialize(secure); -} - -QuicTestClient::QuicTestClient() { -} +QuicTestClient::QuicTestClient() {} QuicTestClient::~QuicTestClient() { if (stream_) {
diff --git a/pdf/out_of_process_instance.cc b/pdf/out_of_process_instance.cc index cfa11ba9..12aad3ca 100644 --- a/pdf/out_of_process_instance.cc +++ b/pdf/out_of_process_instance.cc
@@ -156,6 +156,14 @@ static const char kPPPPdfInterface[] = PPP_PDF_INTERFACE_1; +// Used for UMA. Do not delete entries, and keep in sync with histograms.xml. +enum PDFFeatures { + LOADED_DOCUMENT = 0, + HAS_TITLE = 1, + HAS_BOOKMARKS = 2, + FEATURES_COUNT +}; + PP_Var GetLinkAtPosition(PP_Instance instance, PP_Point point) { pp::Var var; void* object = pp::Instance::GetPerInstanceObject(instance, kPPPPdfInterface); @@ -1101,6 +1109,8 @@ DCHECK(document_load_state_ == LOAD_STATE_LOADING); document_load_state_ = LOAD_STATE_COMPLETE; UserMetricsRecordAction("PDF.LoadSuccess"); + uma_.HistogramEnumeration("PDF.DocumentFeature", LOADED_DOCUMENT, + FEATURES_COUNT); // Note: If we are in print preview mode the scroll location is retained // across document loads so we don't want to scroll again and override it. @@ -1112,10 +1122,17 @@ pp::VarDictionary metadata_message; metadata_message.Set(pp::Var(kType), pp::Var(kJSMetadataType)); std::string title = engine_->GetMetadata("Title"); - if (!base::TrimWhitespace(base::UTF8ToUTF16(title), base::TRIM_ALL).empty()) + if (!base::TrimWhitespace(base::UTF8ToUTF16(title), base::TRIM_ALL).empty()) { metadata_message.Set(pp::Var(kJSTitle), pp::Var(title)); + uma_.HistogramEnumeration("PDF.DocumentFeature", HAS_TITLE, FEATURES_COUNT); + } - metadata_message.Set(pp::Var(kJSBookmarks), engine_->GetBookmarks()); + pp::VarArray bookmarks = engine_->GetBookmarks(); + metadata_message.Set(pp::Var(kJSBookmarks), bookmarks); + if (bookmarks.GetLength() > 0) { + uma_.HistogramEnumeration("PDF.DocumentFeature", HAS_BOOKMARKS, + FEATURES_COUNT); + } PostMessage(metadata_message); pp::VarDictionary progress_message;
diff --git a/ppapi/shared_impl/BUILD.gn b/ppapi/shared_impl/BUILD.gn index 25ad9043..3b92a0a 100644 --- a/ppapi/shared_impl/BUILD.gn +++ b/ppapi/shared_impl/BUILD.gn
@@ -159,6 +159,11 @@ "PPAPI_THUNK_IMPLEMENTATION", ] + public_deps = [ + "//ppapi/c", + "//ppapi/thunk", + ] + deps = [ "//base", "//base:i18n", @@ -169,8 +174,6 @@ "//gpu/command_buffer/common", "//ipc", "//media:shared_memory_support", - "//ppapi/c", - "//ppapi/thunk", "//third_party/icu:icuuc", "//url", ]
diff --git a/remoting/protocol/jingle_session_unittest.cc b/remoting/protocol/jingle_session_unittest.cc index a3e986b..8a643c36 100644 --- a/remoting/protocol/jingle_session_unittest.cc +++ b/remoting/protocol/jingle_session_unittest.cc
@@ -530,11 +530,12 @@ config->PreferTransport(ChannelConfig::TRANSPORT_QUIC_STREAM); client_server_->set_protocol_config(config.Pass()); + ExpectRouteChange(kQuicChannelName); + ASSERT_NO_FATAL_FAILURE( InitiateConnection(1, FakeAuthenticator::ACCEPT, false)); int counter = 2; - ExpectRouteChange(kQuicChannelName); EXPECT_CALL(client_channel_callback_, OnDone(_)) .WillOnce(QuitThreadOnCounter(&counter)); EXPECT_CALL(host_channel_callback_, OnDone(_))
diff --git a/testing/chromoting/browser_tests_launcher.py b/testing/chromoting/browser_tests_launcher.py index 9d33bce4..bb222b7 100644 --- a/testing/chromoting/browser_tests_launcher.py +++ b/testing/chromoting/browser_tests_launcher.py
@@ -7,6 +7,7 @@ import argparse import time +from chromoting_test_utilities import CleanupUserProfileDir from chromoting_test_utilities import GetJidListFromTestResults from chromoting_test_utilities import InitialiseTestMachineForLinux from chromoting_test_utilities import PrintHostLogContents @@ -48,7 +49,10 @@ # It returns the file-name of the me2me host log. # If we are attempting to run this test because of a JID-mismatch, don't # restart host. - if not host_jid_mismatch: + if host_jid_mismatch: + # Cleanup user-profile directory, but don't restart host. + CleanupUserProfileDir(args) + else: host_log_file_names.append(TestCaseSetup(args)) # Parse the me2me host log to obtain the JID that the host registered. host_jid = None
diff --git a/testing/chromoting/chromoting_test_utilities.py b/testing/chromoting/chromoting_test_utilities.py index 79620f43..bcc84d07 100644 --- a/testing/chromoting/chromoting_test_utilities.py +++ b/testing/chromoting/chromoting_test_utilities.py
@@ -152,6 +152,11 @@ return log_file +def CleanupUserProfileDir(args): + SetupUserProfileDir(args.me2me_manifest_file, args.it2me_manifest_file, + args.user_profile_dir) + + def SetupUserProfileDir(me2me_manifest_file, it2me_manifest_file, user_profile_dir): """Sets up the Google Chrome user profile directory. @@ -203,13 +208,10 @@ def TestCaseSetup(args): - # Stop+start me2me host process. - host_log_file = RestartMe2MeHost() - # Reset the user profile directory to start each test with a clean slate. - SetupUserProfileDir(args.me2me_manifest_file, args.it2me_manifest_file, - args.user_profile_dir) - return host_log_file + CleanupUserProfileDir(args) + # Stop+start me2me host process. + return RestartMe2MeHost() def GetJidListFromTestResults(results):
diff --git a/testing/test.gni b/testing/test.gni index 73750394..150c0d8 100644 --- a/testing/test.gni +++ b/testing/test.gni
@@ -80,15 +80,26 @@ } } - test_name = main_target_name + _test_name = main_target_name if (defined(invoker.output_name)) { - test_name = invoker.output_name + _test_name = invoker.output_name } - test_runner_script_name = "${test_name}__test_runner_script" + test_runner_script_name = "${_test_name}__test_runner_script" test_runner_script(test_runner_script_name) { - test_name = test_name + test_name = _test_name test_type = "gtest" - test_suite = test_name + test_suite = _test_name + if (defined(invoker.isolate_file)) { + isolate_file = invoker.isolate_file + } + } + incremental_test_runner_script_name = + "${_test_name}_incremental__test_runner_script" + test_runner_script(incremental_test_runner_script_name) { + test_name = "${_test_name}_incremental" + test_type = "gtest" + test_suite = _test_name + incremental_install = true if (defined(invoker.isolate_file)) { isolate_file = invoker.isolate_file } @@ -100,10 +111,18 @@ ":$test_runner_script_name", ] deps = [ - ":$library_name", ":$apk_name", ] } + group("${target_name}_incremental") { + testonly = true + datadeps = [ + ":$incremental_test_runner_script_name", + ] + deps = [ + ":${apk_name}_incremental", + ] + } } else if (is_ios) { if (is_ios) { import("//build/config/ios/rules.gni")
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index eccd88ac..55f0f7ae 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -691,8 +691,6 @@ crbug.com/443379 imported/web-platform-tests/gamepad/idlharness.html [ Failure Timeout ] -crbug.com/443382 imported/web-platform-tests/subresource-integrity/subresource-integrity.html [ Failure Timeout ] - crbug.com/396775 compositing/overflow/reflected-overlay-scrollbars-should-appear-without-compositing.html [ ImageOnlyFailure ] crbug.com/396775 virtual/prefer_compositing_to_lcd_text/compositing/overflow/reflected-overlay-scrollbars-should-appear-without-compositing.html [ ImageOnlyFailure ] @@ -1617,6 +1615,7 @@ crbug.com/471824 virtual/pointerevent/imported/web-platform-tests/pointerevents/pointerevent_touch-action-verification.html [ Skip ] crbug.com/470429 inspector/tracing/worker-js-profile.html [ Skip ] +crbug.com/470429 virtual/threaded/inspector/tracing/worker-js-profile.html [ Skip ] crbug.com/471066 [ SnowLeopard ] fast/text/apply-start-width-after-skipped-text.html [ Failure ] crbug.com/471066 [ SnowLeopard ] fast/text/bidi-explicit-embedding-past-end.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/W3CImportExpectations b/third_party/WebKit/LayoutTests/W3CImportExpectations index 9ab692da..d267c7b4 100644 --- a/third_party/WebKit/LayoutTests/W3CImportExpectations +++ b/third_party/WebKit/LayoutTests/W3CImportExpectations
@@ -158,8 +158,8 @@ imported/web-platform-tests/service-workers [ Skip ] ## Owners: kochi@chromium.org crbug.com/505364 # imported/web-platform-tests/shadow-dom [ Pass ] -## Owners: mkwst@chromium.org -# imported/web-platform-tests/subresource-integrity [ Pass ] +## Owners: jww@chromium.org +imported/web-platform-tests/subresource-integrity [ Skip ] imported/web-platform-tests/svg [ Skip ] imported/web-platform-tests/tools [ Skip ] imported/web-platform-tests/touch-events [ Skip ]
diff --git a/third_party/WebKit/LayoutTests/fast/forms/select/select-accesskey-change-event.html b/third_party/WebKit/LayoutTests/fast/forms/select/select-accesskey-change-event.html new file mode 100644 index 0000000..00ec32d --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/forms/select/select-accesskey-change-event.html
@@ -0,0 +1,35 @@ +<!DOCTYPE html> +<body> +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> +<div id=log></div> +<select onchange="handleChange();"> +<option accesskey=1 selcted>o1 +<option accesskey=2>o2 +</select> + +<script> +var changeEventCounter = 0; +var select1 = document.querySelector('select'); + +function handleChange() { + ++changeEventCounter; +} + +test(function() { + changeEventCounter = 0; + assert_equals(select1.selectedIndex, 0); + eventSender.keyDown('1', 'accessKey'); + assert_equals(select1.selectedIndex, -1); + assert_equals(changeEventCounter, 1); +}, 'Change event should be dsiaptched after deselecting the selected OPTION by accesskey.'); + +test(function() { + changeEventCounter = 0; + assert_equals(select1.selectedIndex, -1); + eventSender.keyDown('1', 'accessKey'); + assert_equals(select1.selectedIndex, 0); + assert_equals(changeEventCounter, 1); +}, 'Change event should be dsiaptched after selecting the selected OPTION by accesskey again.'); +</script> +</body>
diff --git a/third_party/WebKit/LayoutTests/fast/mediarecorder/BlobEvent-basic.html b/third_party/WebKit/LayoutTests/fast/mediarecorder/BlobEvent-basic.html index 64e9f80..b8c5059 100644 --- a/third_party/WebKit/LayoutTests/fast/mediarecorder/BlobEvent-basic.html +++ b/third_party/WebKit/LayoutTests/fast/mediarecorder/BlobEvent-basic.html
@@ -12,14 +12,10 @@ reader.addEventListener("loadend", function() { // |reader.result| contains the contents of blob as an ArrayBuffer. var outputArray = new Uint8Array(reader.result); - assert_equals(array.length, outputArray.length); - for (var index in outputArray) { - assert_equals(array[index], outputArray[index]); - } + assert_array_equals(array, outputArray) }); reader.readAsArrayBuffer(blob); }, 'check BlobEvent creation and content management'); - </script>
diff --git a/third_party/WebKit/LayoutTests/fast/text/sub-pixel/text-scaling-webfont.html b/third_party/WebKit/LayoutTests/fast/text/sub-pixel/text-scaling-webfont.html index 9a983cb..e4a1481 100644 --- a/third_party/WebKit/LayoutTests/fast/text/sub-pixel/text-scaling-webfont.html +++ b/third_party/WebKit/LayoutTests/fast/text/sub-pixel/text-scaling-webfont.html
@@ -31,18 +31,25 @@ window.testRunner.setTextSubpixelPositioning(true); var PANGRAM = 'My faxed joke won a pager in the cable TV quiz show.'; - var results = runTest(document.getElementById('test'), PANGRAM); - - if (results == PASS) { - testPassed('Size of text scales smoothly and width scales with font size as expected.'); - - // Hide text if test passes as the actual numbers are - // different across platforms and would require platform - // specific baselines. - if (window.testRunner) - document.getElementById('test').style.display = 'none'; - } else { - testFailed('Size of text does not scale smoothly, reported widths highlighted in red do not match reference row.'); + + jsTestIsAsync = true; + document.fonts.ready.then(testAndReport); + + function testAndReport() { + var results = runTest(document.getElementById('test'), PANGRAM); + + if (results == PASS) { + testPassed('Size of text scales smoothly and width scales with font size as expected.'); + + // Hide text if test passes as the actual numbers are + // different across platforms and would require platform + // specific baselines. + if (window.testRunner) + document.getElementById('test').style.display = 'none'; + } else { + testFailed('Size of text does not scale smoothly, reported widths highlighted in red do not match reference row.'); + } + finishJSTest(); } </script> </body>
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/subresource-integrity/alternate.css b/third_party/WebKit/LayoutTests/imported/web-platform-tests/subresource-integrity/alternate.css deleted file mode 100644 index 0ea6d22..0000000 --- a/third_party/WebKit/LayoutTests/imported/web-platform-tests/subresource-integrity/alternate.css +++ /dev/null
@@ -1 +0,0 @@ -.testdiv{ background-color: red }
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/subresource-integrity/crossorigin-anon-script.js b/third_party/WebKit/LayoutTests/imported/web-platform-tests/subresource-integrity/crossorigin-anon-script.js deleted file mode 100644 index 8493585f1..0000000 --- a/third_party/WebKit/LayoutTests/imported/web-platform-tests/subresource-integrity/crossorigin-anon-script.js +++ /dev/null
@@ -1 +0,0 @@ -crossorigin_anon_script=true; \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/subresource-integrity/crossorigin-anon-script.js.headers b/third_party/WebKit/LayoutTests/imported/web-platform-tests/subresource-integrity/crossorigin-anon-script.js.headers deleted file mode 100644 index cb762eff..0000000 --- a/third_party/WebKit/LayoutTests/imported/web-platform-tests/subresource-integrity/crossorigin-anon-script.js.headers +++ /dev/null
@@ -1 +0,0 @@ -Access-Control-Allow-Origin: *
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/subresource-integrity/crossorigin-anon-style.css b/third_party/WebKit/LayoutTests/imported/web-platform-tests/subresource-integrity/crossorigin-anon-style.css deleted file mode 100644 index 3cde4df..0000000 --- a/third_party/WebKit/LayoutTests/imported/web-platform-tests/subresource-integrity/crossorigin-anon-style.css +++ /dev/null
@@ -1 +0,0 @@ -.testdiv{ background-color: yellow }
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/subresource-integrity/crossorigin-anon-style.css.headers b/third_party/WebKit/LayoutTests/imported/web-platform-tests/subresource-integrity/crossorigin-anon-style.css.headers deleted file mode 100644 index cb762eff..0000000 --- a/third_party/WebKit/LayoutTests/imported/web-platform-tests/subresource-integrity/crossorigin-anon-style.css.headers +++ /dev/null
@@ -1 +0,0 @@ -Access-Control-Allow-Origin: *
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/subresource-integrity/crossorigin-creds-script.js b/third_party/WebKit/LayoutTests/imported/web-platform-tests/subresource-integrity/crossorigin-creds-script.js deleted file mode 100644 index 6f39e25..0000000 --- a/third_party/WebKit/LayoutTests/imported/web-platform-tests/subresource-integrity/crossorigin-creds-script.js +++ /dev/null
@@ -1 +0,0 @@ -crossorigin_creds_script=true; \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/subresource-integrity/crossorigin-creds-script.js.sub.headers b/third_party/WebKit/LayoutTests/imported/web-platform-tests/subresource-integrity/crossorigin-creds-script.js.sub.headers deleted file mode 100644 index cf16bd8..0000000 --- a/third_party/WebKit/LayoutTests/imported/web-platform-tests/subresource-integrity/crossorigin-creds-script.js.sub.headers +++ /dev/null
@@ -1,2 +0,0 @@ -Access-Control-Allow-Origin: {{location[scheme]}}://{{domains[]}}:{{location[port]}} -Access-Control-Allow-Credentials: true
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/subresource-integrity/crossorigin-creds-style.css b/third_party/WebKit/LayoutTests/imported/web-platform-tests/subresource-integrity/crossorigin-creds-style.css deleted file mode 100644 index 3cde4df..0000000 --- a/third_party/WebKit/LayoutTests/imported/web-platform-tests/subresource-integrity/crossorigin-creds-style.css +++ /dev/null
@@ -1 +0,0 @@ -.testdiv{ background-color: yellow }
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/subresource-integrity/crossorigin-creds-style.css.sub.headers b/third_party/WebKit/LayoutTests/imported/web-platform-tests/subresource-integrity/crossorigin-creds-style.css.sub.headers deleted file mode 100644 index cf16bd8..0000000 --- a/third_party/WebKit/LayoutTests/imported/web-platform-tests/subresource-integrity/crossorigin-creds-style.css.sub.headers +++ /dev/null
@@ -1,2 +0,0 @@ -Access-Control-Allow-Origin: {{location[scheme]}}://{{domains[]}}:{{location[port]}} -Access-Control-Allow-Credentials: true
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/subresource-integrity/crossorigin-ineligible-script.js b/third_party/WebKit/LayoutTests/imported/web-platform-tests/subresource-integrity/crossorigin-ineligible-script.js deleted file mode 100644 index dd2f968..0000000 --- a/third_party/WebKit/LayoutTests/imported/web-platform-tests/subresource-integrity/crossorigin-ineligible-script.js +++ /dev/null
@@ -1 +0,0 @@ -crossorigin_ineligible_script=true; \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/subresource-integrity/crossorigin-ineligible-style.css b/third_party/WebKit/LayoutTests/imported/web-platform-tests/subresource-integrity/crossorigin-ineligible-style.css deleted file mode 100644 index 3cde4df..0000000 --- a/third_party/WebKit/LayoutTests/imported/web-platform-tests/subresource-integrity/crossorigin-ineligible-style.css +++ /dev/null
@@ -1 +0,0 @@ -.testdiv{ background-color: yellow }
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/subresource-integrity/matching-digest.js b/third_party/WebKit/LayoutTests/imported/web-platform-tests/subresource-integrity/matching-digest.js deleted file mode 100644 index ec41325e..0000000 --- a/third_party/WebKit/LayoutTests/imported/web-platform-tests/subresource-integrity/matching-digest.js +++ /dev/null
@@ -1 +0,0 @@ -matching_digest=true; \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/subresource-integrity/non-matching-digest.js b/third_party/WebKit/LayoutTests/imported/web-platform-tests/subresource-integrity/non-matching-digest.js deleted file mode 100644 index 1b4943e..0000000 --- a/third_party/WebKit/LayoutTests/imported/web-platform-tests/subresource-integrity/non-matching-digest.js +++ /dev/null
@@ -1 +0,0 @@ -non_matching_digest=true; \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/subresource-integrity/style.css b/third_party/WebKit/LayoutTests/imported/web-platform-tests/subresource-integrity/style.css deleted file mode 100644 index 3cde4df..0000000 --- a/third_party/WebKit/LayoutTests/imported/web-platform-tests/subresource-integrity/style.css +++ /dev/null
@@ -1 +0,0 @@ -.testdiv{ background-color: yellow }
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/subresource-integrity/subresource-integrity.html b/third_party/WebKit/LayoutTests/imported/web-platform-tests/subresource-integrity/subresource-integrity.html deleted file mode 100644 index 3dcd94a..0000000 --- a/third_party/WebKit/LayoutTests/imported/web-platform-tests/subresource-integrity/subresource-integrity.html +++ /dev/null
@@ -1,545 +0,0 @@ -<!DOCTYPE html> -<meta charset=utf-8> -<title>Subresource Integrity</title> -<script src="../../../resources/testharness.js"></script> -<script src="../../../resources/testharnessreport.js"></script> - -<div id="log"></div> - -<div id="container"></div> -<script> - // <script> tests - var xorigin_anon_script = location.protocol - + '//www1.' + location.hostname + ':' + location.port - + '/subresource-integrity/crossorigin-anon-script.js'; - - var xorigin_creds_script = location.protocol - + '//www1.' + location.hostname + ':' + location.port - + '/subresource-integrity/crossorigin-creds-script.js'; - - var xorigin_ineligible_script = location.protocol - + '//www1.' + location.hostname + ':' + location.port - + '/subresource-integrity/crossorigin-ineligible-script.js'; - - var SRIScriptTest = function(pass, name, src, integrityValue, crossoriginValue) { - this.pass = pass; - this.name = "Script: " + name; - this.src = src; - this.integrityValue = integrityValue; - this.crossoriginValue = crossoriginValue; - } - - SRIScriptTest.prototype.execute = function() { - var test = async_test(this.name); - var e = document.createElement("script"); - e.src = this.src; - e.setAttribute("integrity", this.integrityValue); - if(this.crossoriginValue) { - e.setAttribute("crossorigin", this.crossoriginValue); - } - if(this.pass) { - e.addEventListener("load", function() {test.done()}); - e.addEventListener("error", function() { - test.step(function(){ assert_unreached("Good load fired error handler.") }) - }); - } else { - e.addEventListener("load", function() { - test.step(function() { assert_unreached("Bad load succeeded.") }) - }); - e.addEventListener("error", function() {test.done()}); - } - document.body.appendChild(e); - }; - - var xorigin_anon_style = location.protocol - + '//www1.' + location.hostname + ':' + location.port - + '/subresource-integrity/crossorigin-anon-style.css'; - - var xorigin_creds_style = location.protocol - + '//www1.' + location.hostname + ':' + location.port - + '/subresource-integrity/crossorigin-creds-style.css'; - - var xorigin_ineligible_style = location.protocol - + '//www1.' + location.hostname + ':' + location.port - + '/subresource-integrity/crossorigin-ineligible-style.css'; - - // <link> tests - // Style tests must be done synchronously because they rely on the presence - // and absence of global style, which can affect later tests. Thus, instead - // of executing them one at a time, the style tests are implemented as a - // queue that builds up a list of tests, and then executes them one at a - // time. - var SRIStyleTest = function(queue, pass, name, attrs, customCallback, altPassValue) { - this.pass = pass; - this.name = "Style: " + name; - this.customCallback = customCallback || function () {}; - this.attrs = attrs || {}; - this.passValue = altPassValue || "rgb(255, 255, 0)"; - - this.test = async_test(this.name); - - this.queue = queue; - this.queue.push(this); - } - - SRIStyleTest.prototype.execute = function() { - var that = this; - var container = document.getElementById("container"); - while (container.hasChildNodes()) { - container.removeChild(container.firstChild); - } - - var test = this.test; - - var div = document.createElement("div"); - div.className = "testdiv"; - var e = document.createElement("link"); - this.attrs.rel = this.attrs.rel || "stylesheet"; - for (var key in this.attrs) { - if (this.attrs.hasOwnProperty(key)) { - e.setAttribute(key, this.attrs[key]); - } - } - - if(this.pass) { - e.addEventListener("load", function() { - test.step(function() { - var background = window.getComputedStyle(div, null).getPropertyValue("background-color"); - assert_equals(background, that.passValue); - test.done(); - }); - }); - e.addEventListener("error", function() { - test.step(function(){ assert_unreached("Good load fired error handler.") }) - }); - } else { - e.addEventListener("load", function() { - test.step(function() { assert_unreached("Bad load succeeded.") }) - }); - e.addEventListener("error", function() { - test.step(function() { - var background = window.getComputedStyle(div, null).getPropertyValue("background-color"); - assert_not_equals(background, that.passValue); - test.done(); - }); - }); - } - container.appendChild(div); - container.appendChild(e); - this.customCallback(e, container); - }; - - var style_tests = []; - style_tests.execute = function() { - if (this.length > 0) { - this.shift().execute(); - } - } - add_result_callback(function(res) { - if (res.name.startsWith("Style: ")) { - style_tests.execute(); - } - }); - - // Script tests - new SRIScriptTest( - true, - "Same-origin with correct sha256 hash.", - "matching-digest.js", - "sha256-U9WYDtBWkcHx13+9UKk/3Q5eoqDc4YGxYb07EPWzb9E=" - ).execute(); - - new SRIScriptTest( - true, - "Same-origin with correct sha384 hash.", - "matching-digest.js", - "sha384-BDRTPSywZFyxfLEAzaLcL4FfERBgJgXfEkuT0r04LG93Yqn1PWNYPZMomaqEfE3H" - ).execute(); - - new SRIScriptTest( - true, - "Same-origin with correct sha512 hash.", - "matching-digest.js", - "sha512-geByvIIRspbnUnwooKGNNCb39nvg+EW0O9hDScTXeo/9pVZztLSUYU3LNV6H0lZapo8bCJUpyPPLAzE9fDzpxg==" - ).execute(); - - new SRIScriptTest( - true, - "Same-origin with empty integrity.", - "matching-digest.js", - "" - ).execute(); - - new SRIScriptTest( - false, - "Same-origin with incorrect hash.", - "non-matching-digest.js", - "sha256-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead" - ).execute(); - - new SRIScriptTest( - true, - "Same-origin with multiple sha256 hashes, including correct.", - "matching-digest.js", - "sha256-U9WYDtBWkcHx13+9UKk/3Q5eoqDc4YGxYb07EPWzb9E= sha256-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead" - ).execute(); - - new SRIScriptTest( - true, - "Same-origin with multiple sha256 hashes, including unknown algorithm.", - "matching-digest.js", - "sha256-U9WYDtBWkcHx13+9UKk/3Q5eoqDc4YGxYb07EPWzb9E= foo666-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead" - ).execute(); - - new SRIScriptTest( - true, - "Same-origin with sha256 mismatch, sha512 match", - "matching-digest.js", - "sha512-geByvIIRspbnUnwooKGNNCb39nvg+EW0O9hDScTXeo/9pVZztLSUYU3LNV6H0lZapo8bCJUpyPPLAzE9fDzpxg== sha256-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead" - ).execute(); - - new SRIScriptTest( - false, - "Same-origin with sha256 match, sha512 mismatch", - "matching-digest.js", - "sha512-deadbeefspbnUnwooKGNNCb39nvg+EW0O9hDScTXeo/9pVZztLSUYU3LNV6H0lZapo8bCJUpyPPLAzE9fDzpxg== sha256-U9WYDtBWkcHx13+9UKk/3Q5eoqDc4YGxYb07EPWzb9E=" - ).execute(); - - new SRIScriptTest( - true, - "<crossorigin='anonymous'> with correct hash, ACAO: *", - xorigin_anon_script, - "sha256-51AjITq701Y0yKSx3/UoIKtIY2UQ9+H8WGyyMuOWOC0=", - "anonymous" - ).execute(); - - new SRIScriptTest( - false, - "<crossorigin='anonymous'> with incorrect hash, ACAO: *", - xorigin_anon_script, - "sha256-deadbeefcSLlbFZCj1OACLxTxVck2TOrBTEdUbwz1yU=", - "anonymous" - ).execute(); - - new SRIScriptTest( - true, - "<crossorigin='use-credentials'> with correct hash, CORS-eligible", - xorigin_creds_script, - "sha256-IaGApVboXPQxVSm2wVFmhMq1Yu37gWklajgMdxKLIvc=", - "use-credentials" - ).execute(); - - new SRIScriptTest( - false, - "<crossorigin='use-credentials'> with incorrect hash CORS-eligible", - xorigin_creds_script, - "sha256-deadbeef2S+pTRZgiw3DWrhC6JLDlt2zRyGpwH7unU8=", - "use-credentials" - ).execute(); - - new SRIScriptTest( - false, - "<crossorigin='anonymous'> with CORS-ineligible resource", - xorigin_ineligible_script, - "sha256-F5fXKTX7SiWjtgybxiBZIo2qhh2WiQnNx372E60XrOo=", - "anonymous" - ).execute(); - - new SRIScriptTest( - false, - "Cross-origin, not CORS request, with correct hash", - xorigin_anon_script, - "sha256-51AjITq701Y0yKSx3/UoIKtIY2UQ9+H8WGyyMuOWOC0=" - ).execute(); - - new SRIScriptTest( - false, - "Cross-origin, not CORS request, with hash mismatch", - xorigin_anon_script, - "sha256-deadbeef01Y0yKSx3/UoIKtIY2UQ9+H8WGyyMuOWOC0=" - ).execute(); - - new SRIScriptTest( - true, - "Cross-origin, empty integrity", - xorigin_anon_script, - "" - ).execute(); - - new SRIScriptTest( - true, - "Same-origin with correct hash, options.", - "matching-digest.js", - "sha256-U9WYDtBWkcHx13+9UKk/3Q5eoqDc4YGxYb07EPWzb9E=?foo=bar?spam=eggs" - ).execute(); - - new SRIScriptTest( - true, - "Same-origin with unknown algorithm only.", - "matching-digest.js", - "foo666-U9WYDtBWkcHx13+9UKk/3Q5eoqDc4YGxYb07EPWzb9E=" - ).execute(); - - // Style tests - new SRIStyleTest( - style_tests, - true, - "Same-origin with correct sha256 hash", - { - href: "style.css?1", - integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4=" - } - ); - - new SRIStyleTest( - style_tests, - true, - "Same-origin with correct sha384 hash", - { - href: "style.css?2", - integrity: "sha384-wDAWxH4tOWBwAwHfBn9B7XuNmFxHTMeigAMwn0iVQ0zq3FtmYMLxihcGnU64CwcX" - } - ); - - new SRIStyleTest( - style_tests, - true, - "Same-origin with correct sha512 hash", - { - href: "style.css?3", - integrity: "sha512-9wXDjd6Wq3H6nPAhI9zOvG7mJkUr03MTxaO+8ztTKnfJif42laL93Be/IF6YYZHHF4esitVYxiwpY2HSZX4l6w==" - } - ); - - new SRIStyleTest( - style_tests, - true, - "Same-origin with empty integrity", - { - href: "style.css?4", - integrity: "" - } - ); - - new SRIStyleTest( - style_tests, - false, - "Same-origin with incorrect hash.", - { - href: "style.css?5", - integrity: "sha256-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead" - } - ); - - new SRIStyleTest( - style_tests, - true, - "Same-origin with multiple sha256 hashes, including correct.", - { - href: "style.css?6", - integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4= sha256-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead" - } - ); - - new SRIStyleTest( - style_tests, - true, - "Same-origin with multiple sha256 hashes, including unknown algorithm.", - { - href: "style.css?7", - integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4= foo666-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead" - } - ); - - new SRIStyleTest( - style_tests, - true, - "Same-origin with sha256 mismatch, sha512 match", - { - href: "style.css?8", - integrity: "sha512-9wXDjd6Wq3H6nPAhI9zOvG7mJkUr03MTxaO+8ztTKnfJif42laL93Be/IF6YYZHHF4esitVYxiwpY2HSZX4l6w== sha256-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead" - } - ); - - new SRIStyleTest( - style_tests, - false, - "Same-origin with sha256 match, sha512 mismatch", - { - href: "style.css?9", - integrity: "sha512-deadbeef9wXDjd6Wq3H6nPAhI9zOvG7mJkUr03MTxaO+8ztTKnfJif42laL93Be/IF6YYZHHF4esitVYxiwpY2== sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4=" - } - ); - - new SRIStyleTest( - style_tests, - true, - "<crossorigin='anonymous'> with correct hash, ACAO: *", - { - href: xorigin_anon_style + '?1', - integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4=", - crossorigin: "anonymous" - } - ); - - new SRIStyleTest( - style_tests, - false, - "<crossorigin='anonymous'> with incorrect hash, ACAO: *", - { - href: xorigin_anon_style + '?2', - integrity: "sha256-deadbeefCzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk=", - crossorigin: "anonymous" - } - ); - - new SRIStyleTest( - style_tests, - true, - "<crossorigin='use-credentials'> with correct hash, CORS-eligible", - { - href: xorigin_creds_style + '?1', - integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4=", - crossorigin: "use-credentials" - } - ); - - new SRIStyleTest( - style_tests, - false, - "<crossorigin='use-credentials'> with incorrect hash CORS-eligible", - { - href: xorigin_creds_style + '?2', - integrity: "sha256-deadbeefCzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk=", - crossorigin: "use-credentials" - } - ); - - new SRIStyleTest( - style_tests, - false, - "<crossorigin='anonymous'> with CORS-ineligible resource", - { - href: xorigin_ineligible_style + '?1', - integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4=", - crossorigin: "anonymous" - } - ); - - new SRIStyleTest( - style_tests, - false, - "Cross-origin, not CORS request, with correct hash", - { - href: xorigin_anon_style + '?3', - integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4=" - } - ); - - new SRIStyleTest( - style_tests, - false, - "Cross-origin, not CORS request, with hash mismatch", - { - href: xorigin_anon_style + '?4', - integrity: "sha256-deadbeefCzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk=" - } - ); - - new SRIStyleTest( - style_tests, - true, - "Cross-origin, empty integrity", - { - href: xorigin_anon_style + '?5', - integrity: "" - } - ); - - new SRIStyleTest( - style_tests, - true, - "Same-origin with correct hash, options.", - { - href: "style.css?10", - integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4=?foo=bar?spam=eggs" - } - ); - - new SRIStyleTest( - style_tests, - true, - "Same-origin with unknown algorithm only.", - { - href: "style.css?11", - integrity: "foo666-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4=?foo=bar?spam=eggs" - } - ); - - new SRIStyleTest( - style_tests, - true, - "Same-origin with correct sha256 hash, rel='stylesheet license'", - { - href: "style.css?12", - integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4=", - rel: "stylesheet license" - } - ); - - new SRIStyleTest( - style_tests, - true, - "Same-origin with correct sha256 hash, rel='license stylesheet'", - { - href: "style.css?13", - integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4=", - rel: "license stylesheet" - } - ); - - new SRIStyleTest( - style_tests, - true, - "Same-origin with correct sha256 and sha512 hash, rel='alternate stylesheet' enabled", - { - href: "alternate.css?1", - title: "alt", - type: "text/css", - class: "alternate", - disabled: "disabled", - rel: "alternate stylesheet", - integrity: "sha256-phbz83bWhnLig+d2VPKrRrTRyhqoDRo1ruGqZLZ0= sha512-8OYEB7ktnzcb6h+kB9CUIuc8qvKIyLpygRJdQSEEycRy74dUsB+Yu9rSjpOPjRUblle8WWX9Gn7v39LK2Oceig==", - }, - function (link, container) { - var alternate = document.querySelector('link.alternate'); - alternate.disabled = false; - }, - "rgb(255, 0, 0)" - ); - - new SRIStyleTest( - style_tests, - false, - "Same-origin with incorrect sha256 and sha512 hash, rel='alternate stylesheet' enabled", - { - href: "alternate.css?2", - title: "alt", - type: "text/css", - class: "alternate", - disabled: "disabled", - rel: "alternate stylesheet", - integrity: "sha256-fail83bWhnLig+d2VPKrRrTRyhqoDRo1ruGqZLZ0= sha512-failB7ktnzcb6h+kB9CUIuc8qvKIyLpygRJdQSEEycRy74dUsB+Yu9rSjpOPjRUblle8WWX9Gn7v39LK2Oceig==", - }, - function (link, container) { - var alternate = document.querySelector('link.alternate'); - alternate.disabled = false; - } - ); - - style_tests.execute(); - -</script> -<!-- TODO check cache-poisoned resources, transfer-encoding, 3xx redirect - to resource with matching hash, and cross-origin leakage test as in sec5.3. - -->
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/accessibility/accessibility-getRelationships-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/accessibility/accessibility-getRelationships-expected.txt index 825de93..7f12afa4 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/accessibility/accessibility-getRelationships-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/accessibility/accessibility-getRelationships-expected.txt
@@ -34,17 +34,19 @@ "name": "activedescendant", "value": { "type": "idref", - "relatedNodeValue": { - "idref": "rg1-r4", - "nodeResult": "li#rg1-r4" - } + "relatedNodes": [ + { + "idref": "rg1-r4", + "nodeResult": "li#rg1-r4" + } + ] } }, { "name": "labelledby", "value": { "type": "idrefList", - "relatedNodeArrayValue": [ + "relatedNodes": [ { "idref": "rg1_label", "nodeResult": "h3#rg1_label" @@ -62,7 +64,7 @@ "type": "relatedElement", "value": { "type": "idrefList", - "relatedNodeArrayValue": [ + "relatedNodes": [ { "idref": "rg1_label", "text": "Lunch Options", @@ -114,7 +116,7 @@ "name": "labelledby", "value": { "type": "idrefList", - "relatedNodeArrayValue": [ + "relatedNodes": [ { "idref": "rg2_label", "nodeResult": "h3#rg2_label" @@ -132,7 +134,7 @@ "type": "relatedElement", "value": { "type": "idrefList", - "relatedNodeArrayValue": [ + "relatedNodes": [ { "idref": "rg2_label", "text": "Drink Options",
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/accessibility/accessibility-getRelationships.html b/third_party/WebKit/LayoutTests/inspector-protocol/accessibility/accessibility-getRelationships.html index 39b0239..0b89b4e 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/accessibility/accessibility-getRelationships.html +++ b/third_party/WebKit/LayoutTests/inspector-protocol/accessibility/accessibility-getRelationships.html
@@ -101,17 +101,13 @@ function rewriteValue(value, promises) { - if (value.type === "idrefList") { - checkExists("relatedNodeArrayValue", value); - var relatedNodeArray = value.relatedNodeArrayValue; - check(Array.isArray(relatedNodeArray), "relatedNodeArrayValue should be an array", JSON.stringify(value)); + if (value.type === "idrefList" || value.type === "idref") { + checkExists("relatedNodes", value); + var relatedNodeArray = value.relatedNodes; + check(Array.isArray(relatedNodeArray), "relatedNodes should be an array", JSON.stringify(value)); for (var relatedNode of relatedNodeArray) { promises.push(rewriteNode(relatedNode)); } - } else if (value.type === "idref") { - checkExists("relatedNodeValue", value); - var relatedNode = value.relatedNodeValue; - promises.push(rewriteNode(relatedNode)); } } function rewriteNodes(msg)
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/accessibility/accessibility-ignoredNodes-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/accessibility/accessibility-ignoredNodes-expected.txt index 640ea0f..d933c02 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/accessibility/accessibility-ignoredNodes-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/accessibility/accessibility-ignoredNodes-expected.txt
@@ -116,9 +116,11 @@ "name": "ancestorDisallowsChild", "value": { "type": "idref", - "relatedNodeValue": { - "backendNodeId": "<string>" - } + "relatedNodes": [ + { + "backendNodeId": "<string>" + } + ] } } ] @@ -140,9 +142,11 @@ "name": "ancestorDisallowsChild", "value": { "type": "idref", - "relatedNodeValue": { - "backendNodeId": "<string>" - } + "relatedNodes": [ + { + "backendNodeId": "<string>" + } + ] } } ] @@ -164,9 +168,11 @@ "name": "ancestorIsLeafNode", "value": { "type": "idref", - "relatedNodeValue": { - "backendNodeId": "<string>" - } + "relatedNodes": [ + { + "backendNodeId": "<string>" + } + ] } } ] @@ -210,10 +216,12 @@ "name": "ariaHiddenRoot", "value": { "type": "idref", - "relatedNodeValue": { - "backendNodeId": "<string>", - "idref": "_6" - } + "relatedNodes": [ + { + "backendNodeId": "<string>", + "idref": "_6" + } + ] } } ] @@ -298,10 +306,12 @@ "name": "inheritsPresentation", "value": { "type": "idref", - "relatedNodeValue": { - "backendNodeId": "<string>", - "idref": "_9" - } + "relatedNodes": [ + { + "backendNodeId": "<string>", + "idref": "_9" + } + ] } } ] @@ -355,10 +365,12 @@ "name": "labelFor", "value": { "type": "idref", - "relatedNodeValue": { - "backendNodeId": "<string>", - "idref": "checkbox" - } + "relatedNodes": [ + { + "backendNodeId": "<string>", + "idref": "checkbox" + } + ] } } ] @@ -380,20 +392,24 @@ "name": "labelContainer", "value": { "type": "idref", - "relatedNodeValue": { - "backendNodeId": "<string>", - "idref": "_12" - } + "relatedNodes": [ + { + "backendNodeId": "<string>", + "idref": "_12" + } + ] } }, { "name": "labelFor", "value": { "type": "idref", - "relatedNodeValue": { - "backendNodeId": "<string>", - "idref": "checkbox" - } + "relatedNodes": [ + { + "backendNodeId": "<string>", + "idref": "checkbox" + } + ] } } ]
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/accessibility/accessibility-ignoredNodesModal-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/accessibility/accessibility-ignoredNodesModal-expected.txt index fc7eb82..e53ea7e0 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/accessibility/accessibility-ignoredNodesModal-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/accessibility/accessibility-ignoredNodesModal-expected.txt
@@ -16,10 +16,12 @@ "name": "activeModalDialog", "value": { "type": "idref", - "relatedNodeValue": { - "backendNodeId": "<string>", - "idref": "_2" - } + "relatedNodes": [ + { + "backendNodeId": "<string>", + "idref": "_2" + } + ] } } ]
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/accessibility/accessibility-ignoredNodesTest.js b/third_party/WebKit/LayoutTests/inspector-protocol/accessibility/accessibility-ignoredNodesTest.js index 6f814b8..34297f7 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/accessibility/accessibility-ignoredNodesTest.js +++ b/third_party/WebKit/LayoutTests/inspector-protocol/accessibility/accessibility-ignoredNodesTest.js
@@ -136,18 +136,13 @@ } var promises = []; for (var property of properties) { - if (property.value.type === "idrefList") { - if (!InspectorTest._checkExists("value.relatedNodeArrayValue", property, reject)) + if (property.value.type === "idrefList" || property.value.type === "idref") { + if (!InspectorTest._checkExists("value.relatedNodes", property, reject)) return; - var relatedNodeArray = property.value.relatedNodeArrayValue; - InspectorTest._check(Array.isArray(relatedNodeArray), "value.relatedNodeArrayValue should be an array", JSON.stringify(property), reject); + var relatedNodeArray = property.value.relatedNodes; + InspectorTest._check(Array.isArray(relatedNodeArray), "value.relatedNodes should be an array", JSON.stringify(property), reject); for (var relatedNode of relatedNodeArray) promises.push(InspectorTest._rewriteNode(relatedNode)); - } else if (property.value.type === "idref") { - if (!InspectorTest._checkExists("value.relatedNodeValue", property, reject)) - return; - var relatedNode = property.value.relatedNodeValue; - promises.push(InspectorTest._rewriteNode(relatedNode)); } }
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-object-preview-expected.txt b/third_party/WebKit/LayoutTests/inspector/console/console-object-preview-expected.txt index 2929ca4..15ba330 100644 --- a/third_party/WebKit/LayoutTests/inspector/console/console-object-preview-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector/console/console-object-preview-expected.txt
@@ -36,22 +36,22 @@ console-object-preview.html:20 [0, 0, 1] console-message-text source-code > console-message-url webkit-html-resource-link > object-value-array source-code > console-object-preview > object-value-number > object-value-number > object-value-number console-object-preview.html:20 [0, 0, 2] console-message-text source-code > console-message-url webkit-html-resource-link > object-value-array source-code > console-object-preview > object-value-number > object-value-number > object-value-number console-object-preview.html:23 Object with many properties console-message-text source-code > console-message-url webkit-html-resource-link -console-object-preview.html:28 Object {property_0: 0, property_1: 1, property_2: 2, property_3: 3, property_4: 4…} console-message-text source-code > console-message-url webkit-html-resource-link > object-value-object source-code > console-view-object-properties-section > tree-outline source-code object-properties-section > parent > selection > console-object-preview > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > object-info-state-note > children +console-object-preview.html:28 Object {property_0: 0, property_1: 1, property_2: 2, property_3: 3, property_4: 4…} console-message-text source-code > console-message-url webkit-html-resource-link > object-value-object source-code > console-view-object-properties-section > tree-outline source-code object-properties-section > parent > selection fill > console-object-preview > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > object-info-state-note > children console-object-preview.html:30 Array with many properties console-message-text source-code > console-message-url webkit-html-resource-link -console-object-preview.html:35 [0, 1, property_0: 0, property_1: 1, property_2: 2, property_3: 3, property_4: 4…] console-message-text source-code > console-message-url webkit-html-resource-link > object-value-array source-code > console-view-object-properties-section > tree-outline source-code object-properties-section > parent > selection > console-object-preview > object-value-number > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > object-info-state-note > children +console-object-preview.html:35 [0, 1, property_0: 0, property_1: 1, property_2: 2, property_3: 3, property_4: 4…] console-message-text source-code > console-message-url webkit-html-resource-link > object-value-array source-code > console-view-object-properties-section > tree-outline source-code object-properties-section > parent > selection fill > console-object-preview > object-value-number > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > object-info-state-note > children console-object-preview.html:37 Object with proto console-message-text source-code > console-message-url webkit-html-resource-link -console-object-preview.html:40 Object {d: 1} console-message-text source-code > console-message-url webkit-html-resource-link > object-value-object source-code > console-view-object-properties-section > tree-outline source-code object-properties-section > parent > selection > console-object-preview > name > object-value-number > object-info-state-note > children +console-object-preview.html:40 Object {d: 1} console-message-text source-code > console-message-url webkit-html-resource-link > object-value-object source-code > console-view-object-properties-section > tree-outline source-code object-properties-section > parent > selection fill > console-object-preview > name > object-value-number > object-info-state-note > children console-object-preview.html:42 Sparse array console-message-text source-code > console-message-url webkit-html-resource-link console-object-preview.html:45 [50: 50] console-message-text source-code > console-message-url webkit-html-resource-link > object-value-array source-code > console-object-preview > name > object-value-number console-object-preview.html:47 Dense array with indexes and propeties console-message-text source-code > console-message-url webkit-html-resource-link -console-object-preview.html:53 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99…] console-message-text source-code > console-message-url webkit-html-resource-link > object-value-array source-code > console-view-object-properties-section > tree-outline source-code object-properties-section > parent > selection > console-object-preview > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-info-state-note > children +console-object-preview.html:53 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99…] console-message-text source-code > console-message-url webkit-html-resource-link > object-value-array source-code > console-view-object-properties-section > tree-outline source-code object-properties-section > parent > selection fill > console-object-preview > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-info-state-note > children console-object-preview.html:55 Object with properties containing whitespaces console-message-text source-code > console-message-url webkit-html-resource-link console-object-preview.html:62 Object {" a b ": " a b ", c d: "c d", "": "", " ": " ", "a↵↵b↵c": "a↵↵b↵c"} console-message-text source-code > console-message-url webkit-html-resource-link > object-value-object source-code > console-object-preview > name > object-value-string > name > object-value-string > name > object-value-string > name > object-value-string > name > object-value-string console-object-preview.html:64 Object with a document.all property console-message-text source-code > console-message-url webkit-html-resource-link -console-object-preview.html:65 Object {all: HTMLAllCollection[7]} console-message-text source-code > console-message-url webkit-html-resource-link > object-value-object source-code > console-view-object-properties-section > tree-outline source-code object-properties-section > parent > selection > console-object-preview > name > object-value-array > object-info-state-note > children +console-object-preview.html:65 Object {all: HTMLAllCollection[7]} console-message-text source-code > console-message-url webkit-html-resource-link > object-value-object source-code > console-view-object-properties-section > tree-outline source-code object-properties-section > parent > selection fill > console-object-preview > name > object-value-array > object-info-state-note > children console-object-preview.html:67 Object with special numbers console-message-text source-code > console-message-url webkit-html-resource-link console-object-preview.html:69 Object {nan: NaN, posInf: Infinity, negInf: -Infinity, negZero: -0} console-message-text source-code > console-message-url webkit-html-resource-link > object-value-object source-code > console-object-preview > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number console-object-preview.html:71 Object with exactly 5 properties: expected to be lossless console-message-text source-code > console-message-url webkit-html-resource-link console-object-preview.html:72 Object {a: 1, b: 2, c: 3, d: 4, e: 5} console-message-text source-code > console-message-url webkit-html-resource-link > object-value-object source-code > console-object-preview > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number -console-object-preview.html:74 Object {null: null, undef: undefined, regexp: /^[regexp]$/g, bool: false} console-message-text source-code > console-message-url webkit-html-resource-link > object-value-object source-code > console-view-object-properties-section > tree-outline source-code object-properties-section > parent > selection > console-object-preview > name > object-value-null > name > object-value-undefined > name > object-value-regexp > name > object-value-boolean > object-info-state-note > children +console-object-preview.html:74 Object {null: null, undef: undefined, regexp: /^[regexp]$/g, bool: false} console-message-text source-code > console-message-url webkit-html-resource-link > object-value-object source-code > console-view-object-properties-section > tree-outline source-code object-properties-section > parent > selection fill > console-object-preview > name > object-value-null > name > object-value-undefined > name > object-value-regexp > name > object-value-boolean > object-info-state-note > children
diff --git a/third_party/WebKit/Source/core/core.gypi b/third_party/WebKit/Source/core/core.gypi index 5e3ab20..d9f411d5 100644 --- a/third_party/WebKit/Source/core/core.gypi +++ b/third_party/WebKit/Source/core/core.gypi
@@ -1769,6 +1769,9 @@ 'inspector/v8/V8InjectedScriptHost.h', 'inspector/v8/V8JavaScriptCallFrame.cpp', 'inspector/v8/V8JavaScriptCallFrame.h', + 'inspector/v8/V8ProfilerAgent.h', + 'inspector/v8/V8ProfilerAgentImpl.cpp', + 'inspector/v8/V8ProfilerAgentImpl.h', 'inspector/v8/V8RuntimeAgent.h', 'inspector/v8/V8RuntimeAgentImpl.cpp', 'inspector/v8/V8RuntimeAgentImpl.h',
diff --git a/third_party/WebKit/Source/core/dom/ContainerNode.cpp b/third_party/WebKit/Source/core/dom/ContainerNode.cpp index 36251dd7..69d4867 100644 --- a/third_party/WebKit/Source/core/dom/ContainerNode.cpp +++ b/third_party/WebKit/Source/core/dom/ContainerNode.cpp
@@ -77,9 +77,8 @@ #if !ENABLE(OILPAN) void ContainerNode::removeDetachedChildren() { - // TODO(bokan): Temporarily made RELEASE_ASSERT to trackdown crbug.com/519752. - RELEASE_ASSERT(!connectedSubframeCount()); - RELEASE_ASSERT(needsAttach()); + ASSERT(!connectedSubframeCount()); + ASSERT(needsAttach()); removeDetachedChildrenInContainer(*this); } #endif
diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp index 9fa9677..122c84f7 100644 --- a/third_party/WebKit/Source/core/dom/Document.cpp +++ b/third_party/WebKit/Source/core/dom/Document.cpp
@@ -2143,7 +2143,7 @@ void Document::detach(const AttachContext& context) { TRACE_EVENT0("blink", "Document::detach"); - ASSERT(!m_frame || m_frame->tree().childCount() == 0); + RELEASE_ASSERT(!m_frame || m_frame->tree().childCount() == 0); if (!isActive()) return; @@ -2244,6 +2244,9 @@ // created by DOMImplementation::createDocument(). DocumentLifecycleNotifier::notifyContextDestroyed(); ExecutionContext::notifyContextDestroyed(); + + // TODO(bokan): Temporarily added this RELEASE_ASSERT to trackdown crbug.com/519752. + RELEASE_ASSERT(!connectedSubframeCount()); } void Document::removeAllEventListeners()
diff --git a/third_party/WebKit/Source/core/dom/Fullscreen.cpp b/third_party/WebKit/Source/core/dom/Fullscreen.cpp index 46c01d3..bc34c3f 100644 --- a/third_party/WebKit/Source/core/dom/Fullscreen.cpp +++ b/third_party/WebKit/Source/core/dom/Fullscreen.cpp
@@ -69,7 +69,7 @@ return !document.settings() || document.settings()->fullscreenSupported(); } -static bool fullscreenElementReady(const Element& element, Fullscreen::RequestType requestType) +static bool fullscreenElementReady(const Element& element) { // A fullscreen element ready check for an element |element| returns true if all of the // following are true, and false otherwise: @@ -98,7 +98,7 @@ // fullscreen element ready check returns true for |element|'s node document's browsing // context's browsing context container, or it has no browsing context container. if (const Element* owner = element.document().ownerElement()) { - if (!fullscreenElementReady(*owner, requestType)) + if (!fullscreenElementReady(*owner)) return false; } @@ -223,7 +223,7 @@ // node document: // The fullscreen element ready check returns false. - if (!fullscreenElementReady(element, requestType)) + if (!fullscreenElementReady(element)) break; // This algorithm is not allowed to show a pop-up: @@ -246,15 +246,15 @@ Document* currentDoc = document(); // 3. Let docs be all doc's ancestor browsing context's documents (if any) and doc. - Deque<Document*> docs; + WillBeHeapDeque<RawPtrWillBeMember<Document>> docs; do { docs.prepend(currentDoc); - currentDoc = currentDoc->ownerElement() ? ¤tDoc->ownerElement()->document() : 0; + currentDoc = currentDoc->ownerElement() ? ¤tDoc->ownerElement()->document() : nullptr; } while (currentDoc); // 4. For each document in docs, run these substeps: - Deque<Document*>::iterator current = docs.begin(), following = docs.begin(); + WillBeHeapDeque<RawPtrWillBeMember<Document>>::iterator current = docs.begin(), following = docs.begin(); do { ++following; @@ -262,7 +262,7 @@ // 1. Let following document be the document after document in docs, or null if there is no // such document. Document* currentDoc = *current; - Document* followingDoc = following != docs.end() ? *following : 0; + Document* followingDoc = following != docs.end() ? *following : nullptr; // 2. If following document is null, push context object on document's fullscreen element // stack, and queue a task to fire an event named fullscreenchange with its bubbles attribute @@ -294,7 +294,7 @@ // 7. Optionally, display a message indicating how the user can exit displaying the context object fullscreen. return; - } while (0); + } while (false); enqueueErrorEvent(element, requestType); }
diff --git a/third_party/WebKit/Source/core/frame/FrameView.cpp b/third_party/WebKit/Source/core/frame/FrameView.cpp index 5356ecb..eff218e 100644 --- a/third_party/WebKit/Source/core/frame/FrameView.cpp +++ b/third_party/WebKit/Source/core/frame/FrameView.cpp
@@ -217,6 +217,17 @@ m_layoutSubtreeRootList.clear(); } +template <typename Function> +void FrameView::forAllFrameViews(Function function) +{ + for (Frame* frame = m_frame.get(); frame; frame = frame->tree().traverseNext(m_frame.get())) { + if (!frame->isLocalFrame()) + continue; + if (FrameView* view = toLocalFrame(frame)->view()) + function(*view); + } +} + void FrameView::removeFromAXObjectCache() { if (AXObjectCache* cache = axObjectCache()) { @@ -1270,14 +1281,9 @@ void FrameView::scrollContentsIfNeededRecursive() { - scrollContentsIfNeeded(); - - for (Frame* child = m_frame->tree().firstChild(); child; child = child->tree().nextSibling()) { - if (!child->isLocalFrame()) - continue; - if (FrameView* view = toLocalFrame(child)->view()) - view->scrollContentsIfNeededRecursive(); - } + forAllFrameViews([](FrameView& frameView) { + frameView.scrollContentsIfNeeded(); + }); } bool FrameView::invalidateViewportConstrainedObjects() @@ -1796,14 +1802,10 @@ void FrameView::updateBackgroundRecursively(const Color& backgroundColor, bool transparent) { - for (Frame* frame = m_frame.get(); frame; frame = frame->tree().traverseNext(m_frame.get())) { - if (!frame->isLocalFrame()) - continue; - if (FrameView* view = toLocalFrame(frame)->view()) { - view->setTransparent(transparent); - view->setBaseBackgroundColor(backgroundColor); - } - } + forAllFrameViews([backgroundColor, transparent](FrameView& frameView) { + frameView.setTransparent(transparent); + frameView.setBaseBackgroundColor(backgroundColor); + }); } void FrameView::scrollToAnchor() @@ -2453,9 +2455,9 @@ { ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); - lifecycle().advanceTo(DocumentLifecycle::InUpdatePaintProperties); + forAllFrameViews([](FrameView& frameView) { frameView.lifecycle().advanceTo(DocumentLifecycle::InUpdatePaintProperties); }); // TODO(pdr): Calculate the paint properties by walking the layout tree. - lifecycle().advanceTo(DocumentLifecycle::UpdatePaintPropertiesClean); + forAllFrameViews([](FrameView& frameView) { frameView.lifecycle().advanceTo(DocumentLifecycle::UpdatePaintPropertiesClean); }); } void FrameView::synchronizedPaint(const LayoutRect* interestRect) @@ -2467,18 +2469,23 @@ ASSERT(view); // TODO(chrishtr): figure out if there can be any GraphicsLayer above this one that draws content. GraphicsLayer* rootGraphicsLayer = view->layer()->graphicsLayerBacking(); - lifecycle().advanceTo(DocumentLifecycle::InPaint); + forAllFrameViews([](FrameView& frameView) { frameView.lifecycle().advanceTo(DocumentLifecycle::InPaint); }); // A null graphics layer can occur for painting of SVG images that are not parented into the main frame tree. if (rootGraphicsLayer) { synchronizedPaintRecursively(rootGraphicsLayer, interestRect); } - lifecycle().advanceTo(DocumentLifecycle::PaintClean); + + forAllFrameViews([](FrameView& frameView) { + frameView.lifecycle().advanceTo(DocumentLifecycle::PaintClean); + frameView.layoutView()->layer()->clearNeedsRepaintRecursively(); + }); } void FrameView::synchronizedPaintRecursively(GraphicsLayer* graphicsLayer, const LayoutRect* interestRect) { - GraphicsContext context(graphicsLayer->paintController()); + ASSERT(graphicsLayer->paintController()); + GraphicsContext context(*graphicsLayer->paintController()); // TODO(chrishtr): fix unit tests to not inject one-off interest rects. if (interestRect) @@ -2489,10 +2496,8 @@ if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled()) graphicsLayer->paintController()->commitNewDisplayItems(graphicsLayer); - for (auto& child : graphicsLayer->children()) { - if (child) - synchronizedPaintRecursively(child, interestRect); - } + for (auto& child : graphicsLayer->children()) + synchronizedPaintRecursively(child, interestRect); } void FrameView::compositeForSlimmingPaintV2() @@ -2500,7 +2505,7 @@ ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); ASSERT(frame() == page()->mainFrame() || (!frame().tree().parent()->isLocalFrame())); - lifecycle().advanceTo(DocumentLifecycle::InCompositingForSlimmingPaintV2); + forAllFrameViews([](FrameView& frameView) { frameView.lifecycle().advanceTo(DocumentLifecycle::InCompositingForSlimmingPaintV2); }); // Detached frames can have no root graphics layer. if (GraphicsLayer* rootGraphicsLayer = layoutView()->layer()->graphicsLayerBacking()) { @@ -2512,7 +2517,7 @@ page()->setCompositedDisplayList(compositedDisplayList.release()); } - lifecycle().advanceTo(DocumentLifecycle::CompositingForSlimmingPaintV2Clean); + forAllFrameViews([](FrameView& frameView) { frameView.lifecycle().advanceTo(DocumentLifecycle::CompositingForSlimmingPaintV2Clean); }); } void FrameView::updateFrameTimingRequestsIfNeeded() @@ -2949,7 +2954,7 @@ Page* page = frame().page(); if (!page || !page->settings().deviceSupportsMouse()) return; - page->chromeClient().setCursor(cursor); + page->chromeClient().setCursor(cursor, m_frame->localFrameRoot()); } void FrameView::frameRectsChanged()
diff --git a/third_party/WebKit/Source/core/frame/FrameView.h b/third_party/WebKit/Source/core/frame/FrameView.h index ac44e9d8..a643ff8 100644 --- a/third_party/WebKit/Source/core/frame/FrameView.h +++ b/third_party/WebKit/Source/core/frame/FrameView.h
@@ -716,6 +716,8 @@ void collectFrameTimingRequests(GraphicsLayerFrameTimingRequests&); void collectFrameTimingRequestsRecursive(GraphicsLayerFrameTimingRequests&); + template <typename Function> void forAllFrameViews(Function); + LayoutSize m_size; typedef HashSet<RefPtr<LayoutEmbeddedObject>> EmbeddedObjectSet;
diff --git a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp index f9b4716..16caece 100644 --- a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
@@ -1979,7 +1979,7 @@ if (m_userGestureRequiredForPlay) { recordAutoplayMetric(PlayMethodFailed); String message = ExceptionMessages::failedToExecute("play", "HTMLMediaElement", "API can only be initiated by a user gesture."); - document().executionContext()->addConsoleMessage(ConsoleMessage::create(JSMessageSource, WarningMessageLevel, message)); + document().addConsoleMessage(ConsoleMessage::create(JSMessageSource, WarningMessageLevel, message)); return; } } else if (m_userGestureRequiredForPlay) {
diff --git a/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp b/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp index e6cdcd7..fd9dda1f 100644 --- a/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp
@@ -42,6 +42,7 @@ #include "core/events/GestureEvent.h" #include "core/events/KeyboardEvent.h" #include "core/events/MouseEvent.h" +#include "core/events/ScopedEventQueue.h" #include "core/frame/FrameHost.h" #include "core/frame/FrameView.h" #include "core/frame/LocalFrame.h" @@ -1705,24 +1706,27 @@ if (!focused()) accessKeyAction(false); - // If this index is already selected, unselect. otherwise update the selected index. const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& items = listItems(); int listIndex = optionToListIndex(index); - if (listIndex >= 0) { - HTMLElement* element = items[listIndex]; - if (isHTMLOptionElement(*element)) { - if (toHTMLOptionElement(*element).selected()) - toHTMLOptionElement(*element).setSelectedState(false); - else - selectOption(index, DispatchInputAndChangeEvent | UserDriven); - } + if (listIndex < 0) + return; + HTMLElement& element = *items[listIndex]; + if (!isHTMLOptionElement(element)) + return; + EventQueueScope scope; + // If this index is already selected, unselect. otherwise update the + // selected index. + if (toHTMLOptionElement(element).selected()) { + if (usesMenuList()) + selectOption(-1, DispatchInputAndChangeEvent | UserDriven); + else + toHTMLOptionElement(element).setSelectedState(false); + } else { + selectOption(index, DispatchInputAndChangeEvent | UserDriven); } - if (usesMenuList()) - dispatchInputAndChangeEventForMenuList(); - else - listBoxOnChange(); - + return; + listBoxOnChange(); scrollToSelection(); }
diff --git a/third_party/WebKit/Source/core/inspector/InspectorProfilerAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorProfilerAgent.cpp index 254e269..3321aef 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorProfilerAgent.cpp +++ b/third_party/WebKit/Source/core/inspector/InspectorProfilerAgent.cpp
@@ -33,134 +33,26 @@ #include "bindings/core/v8/ScriptCallStackFactory.h" #include "bindings/core/v8/V8Binding.h" #include "core/frame/UseCounter.h" -#include "core/inspector/InjectedScript.h" -#include "core/inspector/InjectedScriptHost.h" #include "core/inspector/InspectorState.h" #include "core/inspector/InstrumentingAgents.h" #include "core/inspector/ScriptCallStack.h" -#include <v8-profiler.h> +#include "core/inspector/v8/V8ProfilerAgent.h" namespace blink { namespace ProfilerAgentState { -static const char samplingInterval[] = "samplingInterval"; -static const char userInitiatedProfiling[] = "userInitiatedProfiling"; static const char profilerEnabled[] = "profilerEnabled"; -static const char nextProfileId[] = "nextProfileId"; } -namespace { - -PassRefPtr<TypeBuilder::Array<TypeBuilder::Profiler::PositionTickInfo>> buildInspectorObjectForPositionTicks(const v8::CpuProfileNode* node) +PassOwnPtrWillBeRawPtr<InspectorProfilerAgent> InspectorProfilerAgent::create(v8::Isolate* isolate, Client* client) { - RefPtr<TypeBuilder::Array<TypeBuilder::Profiler::PositionTickInfo>> array = TypeBuilder::Array<TypeBuilder::Profiler::PositionTickInfo>::create(); - unsigned lineCount = node->GetHitLineCount(); - if (!lineCount) - return array.release(); - - Vector<v8::CpuProfileNode::LineTick> entries(lineCount); - if (node->GetLineTicks(&entries[0], lineCount)) { - for (unsigned i = 0; i < lineCount; i++) { - RefPtr<TypeBuilder::Profiler::PositionTickInfo> line = TypeBuilder::Profiler::PositionTickInfo::create() - .setLine(entries[i].line) - .setTicks(entries[i].hit_count); - array->addItem(line); - } - } - - return array.release(); + return adoptPtrWillBeNoop(new InspectorProfilerAgent(isolate, client)); } -PassRefPtr<TypeBuilder::Profiler::CPUProfileNode> buildInspectorObjectFor(const v8::CpuProfileNode* node) -{ - v8::HandleScope handleScope(v8::Isolate::GetCurrent()); - - RefPtr<TypeBuilder::Array<TypeBuilder::Profiler::CPUProfileNode>> children = TypeBuilder::Array<TypeBuilder::Profiler::CPUProfileNode>::create(); - const int childrenCount = node->GetChildrenCount(); - for (int i = 0; i < childrenCount; i++) { - const v8::CpuProfileNode* child = node->GetChild(i); - children->addItem(buildInspectorObjectFor(child)); - } - - RefPtr<TypeBuilder::Array<TypeBuilder::Profiler::PositionTickInfo>> positionTicks = buildInspectorObjectForPositionTicks(node); - - RefPtr<TypeBuilder::Profiler::CPUProfileNode> result = TypeBuilder::Profiler::CPUProfileNode::create() - .setFunctionName(toCoreString(node->GetFunctionName())) - .setScriptId(String::number(node->GetScriptId())) - .setUrl(toCoreString(node->GetScriptResourceName())) - .setLineNumber(node->GetLineNumber()) - .setColumnNumber(node->GetColumnNumber()) - .setHitCount(node->GetHitCount()) - .setCallUID(node->GetCallUid()) - .setChildren(children.release()) - .setPositionTicks(positionTicks.release()) - .setDeoptReason(node->GetBailoutReason()) - .setId(node->GetNodeId()); - return result.release(); -} - -PassRefPtr<TypeBuilder::Array<int>> buildInspectorObjectForSamples(v8::CpuProfile* v8profile) -{ - RefPtr<TypeBuilder::Array<int>> array = TypeBuilder::Array<int>::create(); - int count = v8profile->GetSamplesCount(); - for (int i = 0; i < count; i++) - array->addItem(v8profile->GetSample(i)->GetNodeId()); - return array.release(); -} - -PassRefPtr<TypeBuilder::Array<double>> buildInspectorObjectForTimestamps(v8::CpuProfile* v8profile) -{ - RefPtr<TypeBuilder::Array<double>> array = TypeBuilder::Array<double>::create(); - int count = v8profile->GetSamplesCount(); - for (int i = 0; i < count; i++) - array->addItem(v8profile->GetSampleTimestamp(i)); - return array.release(); -} - -PassRefPtr<TypeBuilder::Profiler::CPUProfile> createCPUProfile(v8::CpuProfile* v8profile) -{ - RefPtr<TypeBuilder::Profiler::CPUProfile> profile = TypeBuilder::Profiler::CPUProfile::create() - .setHead(buildInspectorObjectFor(v8profile->GetTopDownRoot())) - .setStartTime(static_cast<double>(v8profile->GetStartTime()) / 1000000) - .setEndTime(static_cast<double>(v8profile->GetEndTime()) / 1000000); - profile->setSamples(buildInspectorObjectForSamples(v8profile)); - profile->setTimestamps(buildInspectorObjectForTimestamps(v8profile)); - return profile.release(); -} - -PassRefPtr<TypeBuilder::Debugger::Location> currentDebugLocation() -{ - RefPtrWillBeRawPtr<ScriptCallStack> callStack(currentScriptCallStack(1)); - const ScriptCallFrame& lastCaller = callStack->at(0); - RefPtr<TypeBuilder::Debugger::Location> location = TypeBuilder::Debugger::Location::create() - .setScriptId(lastCaller.scriptId()) - .setLineNumber(lastCaller.lineNumber()); - location->setColumnNumber(lastCaller.columnNumber()); - return location.release(); -} - -} // namespace - -class InspectorProfilerAgent::ProfileDescriptor { -public: - ProfileDescriptor(const String& id, const String& title) - : m_id(id) - , m_title(title) { } - String m_id; - String m_title; -}; - -PassOwnPtrWillBeRawPtr<InspectorProfilerAgent> InspectorProfilerAgent::create(v8::Isolate* isolate, InjectedScriptManager* injectedScriptManager, Client* client) -{ - return adoptPtrWillBeNoop(new InspectorProfilerAgent(isolate, injectedScriptManager, client)); -} - -InspectorProfilerAgent::InspectorProfilerAgent(v8::Isolate* isolate, InjectedScriptManager* injectedScriptManager, Client* client) +InspectorProfilerAgent::InspectorProfilerAgent(v8::Isolate* isolate, Client* client) : InspectorBaseAgent<InspectorProfilerAgent, InspectorFrontend::Profiler>("Profiler") - , m_isolate(isolate) - , m_injectedScriptManager(injectedScriptManager) - , m_recordingCPUProfile(false) , m_client(client) + , m_v8ProfilerAgent(V8ProfilerAgent::create(isolate)) { } @@ -168,204 +60,100 @@ { } -void InspectorProfilerAgent::consoleProfile(ExecutionContext* context, const String& title) +// InspectorBaseAgent overrides. +void InspectorProfilerAgent::init() { - UseCounter::count(context, UseCounter::DevToolsConsoleProfile); - ASSERT(frontend() && enabled()); - String id = nextProfileId(); - m_startedProfiles.append(ProfileDescriptor(id, title)); - startProfiling(id); - frontend()->consoleProfileStarted(id, currentDebugLocation(), title.isNull() ? 0 : &title); + m_v8ProfilerAgent->setInspectorState(m_state); } -void InspectorProfilerAgent::consoleProfileEnd(const String& title) +void InspectorProfilerAgent::setFrontend(InspectorFrontend* frontend) { - ASSERT(frontend() && enabled()); - String id; - String resolvedTitle; - // Take last started profile if no title was passed. - if (title.isNull()) { - if (m_startedProfiles.isEmpty()) - return; - id = m_startedProfiles.last().m_id; - resolvedTitle = m_startedProfiles.last().m_title; - m_startedProfiles.removeLast(); - } else { - for (size_t i = 0; i < m_startedProfiles.size(); i++) { - if (m_startedProfiles[i].m_title == title) { - resolvedTitle = title; - id = m_startedProfiles[i].m_id; - m_startedProfiles.remove(i); - break; - } - } - if (id.isEmpty()) - return; - } - RefPtr<TypeBuilder::Profiler::CPUProfile> profile = stopProfiling(id, true); - if (!profile) - return; - RefPtr<TypeBuilder::Debugger::Location> location = currentDebugLocation(); - frontend()->consoleProfileFinished(id, location, profile, resolvedTitle.isNull() ? 0 : &resolvedTitle); + InspectorBaseAgent::setFrontend(frontend); + m_v8ProfilerAgent->setFrontend(InspectorFrontend::Profiler::from(frontend)); } -void InspectorProfilerAgent::enable(ErrorString*) +void InspectorProfilerAgent::clearFrontend() { - m_state->setBoolean(ProfilerAgentState::profilerEnabled, true); - doEnable(); -} - -void InspectorProfilerAgent::doEnable() -{ - m_instrumentingAgents->setInspectorProfilerAgent(this); -} - -void InspectorProfilerAgent::disable(ErrorString*) -{ - for (Vector<ProfileDescriptor>::reverse_iterator it = m_startedProfiles.rbegin(); it != m_startedProfiles.rend(); ++it) - stopProfiling(it->m_id, false); - m_startedProfiles.clear(); - stop(0, 0); - m_instrumentingAgents->setInspectorProfilerAgent(nullptr); - m_state->setBoolean(ProfilerAgentState::profilerEnabled, false); -} - -bool InspectorProfilerAgent::enabled() -{ - return m_state->getBoolean(ProfilerAgentState::profilerEnabled); -} - -void InspectorProfilerAgent::setSamplingInterval(ErrorString* error, int interval) -{ - if (m_recordingCPUProfile) { - *error = "Cannot change sampling interval when profiling."; - return; - } - m_state->setLong(ProfilerAgentState::samplingInterval, interval); - m_isolate->GetCpuProfiler()->SetSamplingInterval(interval); + m_v8ProfilerAgent->clearFrontend(); + InspectorBaseAgent::clearFrontend(); } void InspectorProfilerAgent::restore() { - if (m_state->getBoolean(ProfilerAgentState::profilerEnabled)) - doEnable(); - if (long interval = m_state->getLong(ProfilerAgentState::samplingInterval, 0)) - m_isolate->GetCpuProfiler()->SetSamplingInterval(interval); - if (m_state->getBoolean(ProfilerAgentState::userInitiatedProfiling)) { - ErrorString error; - start(&error); - } + if (!m_state->getBoolean(ProfilerAgentState::profilerEnabled)) + return; + m_v8ProfilerAgent->restore(); + ErrorString errorString; + enable(&errorString); +} + +// Protocol implementation. +void InspectorProfilerAgent::consoleProfile(ExecutionContext* context, const String& title) +{ + UseCounter::count(context, UseCounter::DevToolsConsoleProfile); + m_v8ProfilerAgent->consoleProfile(title); +} + +void InspectorProfilerAgent::consoleProfileEnd(const String& title) +{ + m_v8ProfilerAgent->consoleProfileEnd(title); +} + +void InspectorProfilerAgent::enable(ErrorString* errorString) +{ + m_v8ProfilerAgent->enable(errorString); + m_state->setBoolean(ProfilerAgentState::profilerEnabled, true); + m_instrumentingAgents->setInspectorProfilerAgent(this); +} + +void InspectorProfilerAgent::disable(ErrorString* errorString) +{ + m_instrumentingAgents->setInspectorProfilerAgent(nullptr); + m_state->setBoolean(ProfilerAgentState::profilerEnabled, false); + m_v8ProfilerAgent->disable(errorString); +} + +void InspectorProfilerAgent::setSamplingInterval(ErrorString* error, int interval) +{ + m_v8ProfilerAgent->setSamplingInterval(error, interval); } void InspectorProfilerAgent::start(ErrorString* error) { - if (m_recordingCPUProfile) - return; - if (!enabled()) { - *error = "Profiler is not enabled"; - return; - } - m_recordingCPUProfile = true; - if (m_client) + m_v8ProfilerAgent->start(error); + if (m_client && !*error) m_client->profilingStarted(); - m_frontendInitiatedProfileId = nextProfileId(); - startProfiling(m_frontendInitiatedProfileId); - m_state->setBoolean(ProfilerAgentState::userInitiatedProfiling, true); } void InspectorProfilerAgent::stop(ErrorString* errorString, RefPtr<TypeBuilder::Profiler::CPUProfile>& profile) { - stop(errorString, &profile); -} - -void InspectorProfilerAgent::stop(ErrorString* errorString, RefPtr<TypeBuilder::Profiler::CPUProfile>* profile) -{ - if (!m_recordingCPUProfile) { - if (errorString) - *errorString = "No recording profiles found"; - return; - } - m_recordingCPUProfile = false; if (m_client) m_client->profilingStopped(); - RefPtr<TypeBuilder::Profiler::CPUProfile> cpuProfile = stopProfiling(m_frontendInitiatedProfileId, !!profile); - if (profile) { - *profile = cpuProfile; - if (!cpuProfile && errorString) - *errorString = "Profile wasn't found"; - } - m_frontendInitiatedProfileId = String(); - m_state->setBoolean(ProfilerAgentState::userInitiatedProfiling, false); -} - -String InspectorProfilerAgent::nextProfileId() -{ - long nextId = m_state->getLong(ProfilerAgentState::nextProfileId, 1); - m_state->setLong(ProfilerAgentState::nextProfileId, nextId + 1); - return String::number(nextId); -} - -void InspectorProfilerAgent::startProfiling(const String& title) -{ - v8::HandleScope handleScope(m_isolate); - m_isolate->GetCpuProfiler()->StartProfiling(v8String(m_isolate, title), true); -} - -PassRefPtr<TypeBuilder::Profiler::CPUProfile> InspectorProfilerAgent::stopProfiling(const String& title, bool serialize) -{ - v8::HandleScope handleScope(m_isolate); - v8::CpuProfile* profile = m_isolate->GetCpuProfiler()->StopProfiling(v8String(m_isolate, title)); - if (!profile) - return nullptr; - RefPtr<TypeBuilder::Profiler::CPUProfile> result; - if (serialize) - result = createCPUProfile(profile); - profile->Delete(); - return result.release(); -} - -bool InspectorProfilerAgent::isRecording() const -{ - return m_recordingCPUProfile || !m_startedProfiles.isEmpty(); -} - -void InspectorProfilerAgent::idleFinished() -{ - if (!isRecording()) - return; - m_isolate->GetCpuProfiler()->SetIdle(false); -} - -void InspectorProfilerAgent::idleStarted() -{ - if (!isRecording()) - return; - m_isolate->GetCpuProfiler()->SetIdle(true); + m_v8ProfilerAgent->stop(errorString, profile); } void InspectorProfilerAgent::willProcessTask() { - idleFinished(); + m_v8ProfilerAgent->idleFinished(); } void InspectorProfilerAgent::didProcessTask() { - idleStarted(); + m_v8ProfilerAgent->idleStarted(); } void InspectorProfilerAgent::willEnterNestedRunLoop() { - idleStarted(); + m_v8ProfilerAgent->idleStarted(); } void InspectorProfilerAgent::didLeaveNestedRunLoop() { - idleFinished(); + m_v8ProfilerAgent->idleFinished(); } DEFINE_TRACE(InspectorProfilerAgent) { - visitor->trace(m_injectedScriptManager); InspectorBaseAgent::trace(visitor); }
diff --git a/third_party/WebKit/Source/core/inspector/InspectorProfilerAgent.h b/third_party/WebKit/Source/core/inspector/InspectorProfilerAgent.h index 61640db7..2da64d3 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorProfilerAgent.h +++ b/third_party/WebKit/Source/core/inspector/InspectorProfilerAgent.h
@@ -34,20 +34,15 @@ #include "core/InspectorFrontend.h" #include "core/inspector/InspectorBaseAgent.h" #include "wtf/Forward.h" -#include "wtf/HashMap.h" #include "wtf/Noncopyable.h" #include "wtf/PassOwnPtr.h" #include "wtf/text/WTFString.h" -namespace v8 { -class CpuProfile; -} - namespace blink { class ExecutionContext; -class InjectedScriptManager; class InspectorFrontend; +class V8ProfilerAgent; typedef String ErrorString; @@ -62,47 +57,35 @@ virtual void profilingStopped() { } }; - static PassOwnPtrWillBeRawPtr<InspectorProfilerAgent> create(v8::Isolate*, InjectedScriptManager*, Client*); + static PassOwnPtrWillBeRawPtr<InspectorProfilerAgent> create(v8::Isolate*, Client*); ~InspectorProfilerAgent() override; DECLARE_VIRTUAL_TRACE(); + // InspectorBaseAgent overrides. + void init() override; + void setFrontend(InspectorFrontend*) override; + void clearFrontend() override; + void restore() override; + void consoleProfile(ExecutionContext*, const String& title); void consoleProfileEnd(const String& title); void enable(ErrorString*) override; + void disable(ErrorString*) override; void setSamplingInterval(ErrorString*, int) override; void start(ErrorString*) override; void stop(ErrorString*, RefPtr<TypeBuilder::Profiler::CPUProfile>&) override; - void disable(ErrorString*) override; - void restore() override; - void willProcessTask(); void didProcessTask(); void willEnterNestedRunLoop(); void didLeaveNestedRunLoop(); private: - InspectorProfilerAgent(v8::Isolate*, InjectedScriptManager*, Client*); - bool enabled(); - void doEnable(); - void stop(ErrorString*, RefPtr<TypeBuilder::Profiler::CPUProfile>*); - String nextProfileId(); + InspectorProfilerAgent(v8::Isolate*, Client*); - void startProfiling(const String& title); - PassRefPtr<TypeBuilder::Profiler::CPUProfile> stopProfiling(const String& title, bool serialize); - - bool isRecording() const; - void idleStarted(); - void idleFinished(); - - v8::Isolate* m_isolate; - RawPtrWillBeMember<InjectedScriptManager> m_injectedScriptManager; - bool m_recordingCPUProfile; - class ProfileDescriptor; - Vector<ProfileDescriptor> m_startedProfiles; - String m_frontendInitiatedProfileId; Client* m_client; + OwnPtr<V8ProfilerAgent> m_v8ProfilerAgent; }; } // namespace blink
diff --git a/third_party/WebKit/Source/core/inspector/WorkerInspectorController.cpp b/third_party/WebKit/Source/core/inspector/WorkerInspectorController.cpp index f6c31aa..31822ea 100644 --- a/third_party/WebKit/Source/core/inspector/WorkerInspectorController.cpp +++ b/third_party/WebKit/Source/core/inspector/WorkerInspectorController.cpp
@@ -136,7 +136,7 @@ m_agents.append(workerDebuggerAgent.release()); v8::Isolate* isolate = workerGlobalScope->thread()->isolate(); - m_agents.append(InspectorProfilerAgent::create(isolate, m_injectedScriptManager.get(), 0)); + m_agents.append(InspectorProfilerAgent::create(isolate, 0)); m_agents.append(InspectorHeapProfilerAgent::create(isolate, m_injectedScriptManager.get())); OwnPtrWillBeRawPtr<WorkerConsoleAgent> workerConsoleAgent = WorkerConsoleAgent::create(m_injectedScriptManager.get(), workerGlobalScope);
diff --git a/third_party/WebKit/Source/core/inspector/v8/V8ProfilerAgent.h b/third_party/WebKit/Source/core/inspector/v8/V8ProfilerAgent.h new file mode 100644 index 0000000..6e375f9 --- /dev/null +++ b/third_party/WebKit/Source/core/inspector/v8/V8ProfilerAgent.h
@@ -0,0 +1,53 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8ProfilerAgent_h +#define V8ProfilerAgent_h + +#include "core/CoreExport.h" +#include "core/InspectorFrontend.h" +#include "wtf/Forward.h" +#include "wtf/Noncopyable.h" +#include "wtf/text/WTFString.h" + +namespace v8 { +class Isolate; +} + +namespace blink { + +class InspectorState; + +typedef String ErrorString; + +class CORE_EXPORT V8ProfilerAgent { +public: + static PassOwnPtr<V8ProfilerAgent> create(v8::Isolate*); + virtual ~V8ProfilerAgent() { } + + // State management methods. + virtual void setInspectorState(InspectorState*) = 0; + virtual void setFrontend(InspectorFrontend::Profiler*) = 0; + virtual void clearFrontend() = 0; + virtual void restore() = 0; + + // Protocol methods. + virtual void enable(ErrorString*) = 0; + virtual void disable(ErrorString*) = 0; + virtual void setSamplingInterval(ErrorString*, int) = 0; + virtual void start(ErrorString*) = 0; + virtual void stop(ErrorString*, RefPtr<TypeBuilder::Profiler::CPUProfile>&) = 0; + + // API for the embedder. + virtual void consoleProfile(const String& title) = 0; + virtual void consoleProfileEnd(const String& title) = 0; + + virtual void idleStarted() = 0; + virtual void idleFinished() = 0; +}; + +} // namespace blink + + +#endif // !defined(V8ProfilerAgent_h)
diff --git a/third_party/WebKit/Source/core/inspector/v8/V8ProfilerAgentImpl.cpp b/third_party/WebKit/Source/core/inspector/v8/V8ProfilerAgentImpl.cpp new file mode 100644 index 0000000..bf9afa9f --- /dev/null +++ b/third_party/WebKit/Source/core/inspector/v8/V8ProfilerAgentImpl.cpp
@@ -0,0 +1,306 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "config.h" +#include "core/inspector/v8/V8ProfilerAgentImpl.h" + +#include "bindings/core/v8/ScriptCallStackFactory.h" +#include "bindings/core/v8/V8Binding.h" +#include "core/inspector/InspectorState.h" +#include "core/inspector/ScriptCallStack.h" +#include <v8-profiler.h> + +namespace blink { + +namespace ProfilerAgentState { +static const char samplingInterval[] = "samplingInterval"; +static const char userInitiatedProfiling[] = "userInitiatedProfiling"; +static const char nextProfileId[] = "nextProfileId"; +} + +namespace { + +PassRefPtr<TypeBuilder::Array<TypeBuilder::Profiler::PositionTickInfo>> buildInspectorObjectForPositionTicks(const v8::CpuProfileNode* node) +{ + RefPtr<TypeBuilder::Array<TypeBuilder::Profiler::PositionTickInfo>> array = TypeBuilder::Array<TypeBuilder::Profiler::PositionTickInfo>::create(); + unsigned lineCount = node->GetHitLineCount(); + if (!lineCount) + return array.release(); + + Vector<v8::CpuProfileNode::LineTick> entries(lineCount); + if (node->GetLineTicks(&entries[0], lineCount)) { + for (unsigned i = 0; i < lineCount; i++) { + RefPtr<TypeBuilder::Profiler::PositionTickInfo> line = TypeBuilder::Profiler::PositionTickInfo::create() + .setLine(entries[i].line) + .setTicks(entries[i].hit_count); + array->addItem(line); + } + } + + return array.release(); +} + +PassRefPtr<TypeBuilder::Profiler::CPUProfileNode> buildInspectorObjectFor(const v8::CpuProfileNode* node) +{ + v8::HandleScope handleScope(v8::Isolate::GetCurrent()); + + RefPtr<TypeBuilder::Array<TypeBuilder::Profiler::CPUProfileNode>> children = TypeBuilder::Array<TypeBuilder::Profiler::CPUProfileNode>::create(); + const int childrenCount = node->GetChildrenCount(); + for (int i = 0; i < childrenCount; i++) { + const v8::CpuProfileNode* child = node->GetChild(i); + children->addItem(buildInspectorObjectFor(child)); + } + + RefPtr<TypeBuilder::Array<TypeBuilder::Profiler::PositionTickInfo>> positionTicks = buildInspectorObjectForPositionTicks(node); + + RefPtr<TypeBuilder::Profiler::CPUProfileNode> result = TypeBuilder::Profiler::CPUProfileNode::create() + .setFunctionName(toCoreString(node->GetFunctionName())) + .setScriptId(String::number(node->GetScriptId())) + .setUrl(toCoreString(node->GetScriptResourceName())) + .setLineNumber(node->GetLineNumber()) + .setColumnNumber(node->GetColumnNumber()) + .setHitCount(node->GetHitCount()) + .setCallUID(node->GetCallUid()) + .setChildren(children.release()) + .setPositionTicks(positionTicks.release()) + .setDeoptReason(node->GetBailoutReason()) + .setId(node->GetNodeId()); + return result.release(); +} + +PassRefPtr<TypeBuilder::Array<int>> buildInspectorObjectForSamples(v8::CpuProfile* v8profile) +{ + RefPtr<TypeBuilder::Array<int>> array = TypeBuilder::Array<int>::create(); + int count = v8profile->GetSamplesCount(); + for (int i = 0; i < count; i++) + array->addItem(v8profile->GetSample(i)->GetNodeId()); + return array.release(); +} + +PassRefPtr<TypeBuilder::Array<double>> buildInspectorObjectForTimestamps(v8::CpuProfile* v8profile) +{ + RefPtr<TypeBuilder::Array<double>> array = TypeBuilder::Array<double>::create(); + int count = v8profile->GetSamplesCount(); + for (int i = 0; i < count; i++) + array->addItem(v8profile->GetSampleTimestamp(i)); + return array.release(); +} + +PassRefPtr<TypeBuilder::Profiler::CPUProfile> createCPUProfile(v8::CpuProfile* v8profile) +{ + RefPtr<TypeBuilder::Profiler::CPUProfile> profile = TypeBuilder::Profiler::CPUProfile::create() + .setHead(buildInspectorObjectFor(v8profile->GetTopDownRoot())) + .setStartTime(static_cast<double>(v8profile->GetStartTime()) / 1000000) + .setEndTime(static_cast<double>(v8profile->GetEndTime()) / 1000000); + profile->setSamples(buildInspectorObjectForSamples(v8profile)); + profile->setTimestamps(buildInspectorObjectForTimestamps(v8profile)); + return profile.release(); +} + +PassRefPtr<TypeBuilder::Debugger::Location> currentDebugLocation() +{ + RefPtrWillBeRawPtr<ScriptCallStack> callStack(currentScriptCallStack(1)); + const ScriptCallFrame& lastCaller = callStack->at(0); + RefPtr<TypeBuilder::Debugger::Location> location = TypeBuilder::Debugger::Location::create() + .setScriptId(lastCaller.scriptId()) + .setLineNumber(lastCaller.lineNumber()); + location->setColumnNumber(lastCaller.columnNumber()); + return location.release(); +} + +} // namespace + +class V8ProfilerAgentImpl::ProfileDescriptor { +public: + ProfileDescriptor(const String& id, const String& title) + : m_id(id) + , m_title(title) { } + String m_id; + String m_title; +}; + +PassOwnPtr<V8ProfilerAgent> V8ProfilerAgent::create(v8::Isolate* isolate) +{ + return adoptPtr(new V8ProfilerAgentImpl(isolate)); +} + +V8ProfilerAgentImpl::V8ProfilerAgentImpl(v8::Isolate* isolate) + : m_isolate(isolate) + , m_state(nullptr) + , m_frontend(nullptr) + , m_enabled(false) + , m_recordingCPUProfile(false) +{ +} + +V8ProfilerAgentImpl::~V8ProfilerAgentImpl() +{ +} + +void V8ProfilerAgentImpl::consoleProfile(const String& title) +{ + ASSERT(m_frontend && m_enabled); + String id = nextProfileId(); + m_startedProfiles.append(ProfileDescriptor(id, title)); + startProfiling(id); + m_frontend->consoleProfileStarted(id, currentDebugLocation(), title.isNull() ? 0 : &title); +} + +void V8ProfilerAgentImpl::consoleProfileEnd(const String& title) +{ + ASSERT(m_frontend && m_enabled); + String id; + String resolvedTitle; + // Take last started profile if no title was passed. + if (title.isNull()) { + if (m_startedProfiles.isEmpty()) + return; + id = m_startedProfiles.last().m_id; + resolvedTitle = m_startedProfiles.last().m_title; + m_startedProfiles.removeLast(); + } else { + for (size_t i = 0; i < m_startedProfiles.size(); i++) { + if (m_startedProfiles[i].m_title == title) { + resolvedTitle = title; + id = m_startedProfiles[i].m_id; + m_startedProfiles.remove(i); + break; + } + } + if (id.isEmpty()) + return; + } + RefPtr<TypeBuilder::Profiler::CPUProfile> profile = stopProfiling(id, true); + if (!profile) + return; + RefPtr<TypeBuilder::Debugger::Location> location = currentDebugLocation(); + m_frontend->consoleProfileFinished(id, location, profile, resolvedTitle.isNull() ? 0 : &resolvedTitle); +} + +void V8ProfilerAgentImpl::enable(ErrorString*) +{ + m_enabled = true; +} + +void V8ProfilerAgentImpl::disable(ErrorString*) +{ + for (Vector<ProfileDescriptor>::reverse_iterator it = m_startedProfiles.rbegin(); it != m_startedProfiles.rend(); ++it) + stopProfiling(it->m_id, false); + m_startedProfiles.clear(); + stop(0, 0); + m_enabled = false; +} + +void V8ProfilerAgentImpl::setSamplingInterval(ErrorString* error, int interval) +{ + if (m_recordingCPUProfile) { + *error = "Cannot change sampling interval when profiling."; + return; + } + m_state->setLong(ProfilerAgentState::samplingInterval, interval); + m_isolate->GetCpuProfiler()->SetSamplingInterval(interval); +} + +void V8ProfilerAgentImpl::clearFrontend() +{ + ErrorString error; + disable(&error); + ASSERT(m_frontend); + m_frontend = nullptr; +} + +void V8ProfilerAgentImpl::restore() +{ + m_enabled = true; + if (long interval = m_state->getLong(ProfilerAgentState::samplingInterval, 0)) + m_isolate->GetCpuProfiler()->SetSamplingInterval(interval); + if (m_state->getBoolean(ProfilerAgentState::userInitiatedProfiling)) { + ErrorString error; + start(&error); + } +} + +void V8ProfilerAgentImpl::start(ErrorString* error) +{ + if (m_recordingCPUProfile) + return; + if (!m_enabled) { + *error = "Profiler is not enabled"; + return; + } + m_recordingCPUProfile = true; + m_frontendInitiatedProfileId = nextProfileId(); + startProfiling(m_frontendInitiatedProfileId); + m_state->setBoolean(ProfilerAgentState::userInitiatedProfiling, true); +} + +void V8ProfilerAgentImpl::stop(ErrorString* errorString, RefPtr<TypeBuilder::Profiler::CPUProfile>& profile) +{ + stop(errorString, &profile); +} + +void V8ProfilerAgentImpl::stop(ErrorString* errorString, RefPtr<TypeBuilder::Profiler::CPUProfile>* profile) +{ + if (!m_recordingCPUProfile) { + if (errorString) + *errorString = "No recording profiles found"; + return; + } + m_recordingCPUProfile = false; + RefPtr<TypeBuilder::Profiler::CPUProfile> cpuProfile = stopProfiling(m_frontendInitiatedProfileId, !!profile); + if (profile) { + *profile = cpuProfile; + if (!cpuProfile && errorString) + *errorString = "Profile wasn't found"; + } + m_frontendInitiatedProfileId = String(); + m_state->setBoolean(ProfilerAgentState::userInitiatedProfiling, false); +} + +String V8ProfilerAgentImpl::nextProfileId() +{ + long nextId = m_state->getLong(ProfilerAgentState::nextProfileId, 1); + m_state->setLong(ProfilerAgentState::nextProfileId, nextId + 1); + return String::number(nextId); +} + +void V8ProfilerAgentImpl::startProfiling(const String& title) +{ + v8::HandleScope handleScope(m_isolate); + m_isolate->GetCpuProfiler()->StartProfiling(v8String(m_isolate, title), true); +} + +PassRefPtr<TypeBuilder::Profiler::CPUProfile> V8ProfilerAgentImpl::stopProfiling(const String& title, bool serialize) +{ + v8::HandleScope handleScope(m_isolate); + v8::CpuProfile* profile = m_isolate->GetCpuProfiler()->StopProfiling(v8String(m_isolate, title)); + if (!profile) + return nullptr; + RefPtr<TypeBuilder::Profiler::CPUProfile> result; + if (serialize) + result = createCPUProfile(profile); + profile->Delete(); + return result.release(); +} + +bool V8ProfilerAgentImpl::isRecording() const +{ + return m_recordingCPUProfile || !m_startedProfiles.isEmpty(); +} + +void V8ProfilerAgentImpl::idleFinished() +{ + if (!isRecording()) + return; + m_isolate->GetCpuProfiler()->SetIdle(false); +} + +void V8ProfilerAgentImpl::idleStarted() +{ + if (!isRecording()) + return; + m_isolate->GetCpuProfiler()->SetIdle(true); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/core/inspector/v8/V8ProfilerAgentImpl.h b/third_party/WebKit/Source/core/inspector/v8/V8ProfilerAgentImpl.h new file mode 100644 index 0000000..7ba14e0 --- /dev/null +++ b/third_party/WebKit/Source/core/inspector/v8/V8ProfilerAgentImpl.h
@@ -0,0 +1,62 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8ProfilerAgentImpl_h +#define V8ProfilerAgentImpl_h + +#include "core/CoreExport.h" +#include "core/InspectorFrontend.h" +#include "core/inspector/v8/V8ProfilerAgent.h" +#include "wtf/Forward.h" +#include "wtf/Noncopyable.h" +#include "wtf/text/WTFString.h" + +namespace blink { + +class CORE_EXPORT V8ProfilerAgentImpl : public V8ProfilerAgent { + WTF_MAKE_NONCOPYABLE(V8ProfilerAgentImpl); +public: + explicit V8ProfilerAgentImpl(v8::Isolate*); + ~V8ProfilerAgentImpl() override; + + void setInspectorState(InspectorState* state) override { m_state = state; } + void setFrontend(InspectorFrontend::Profiler* frontend) override { m_frontend = frontend; } + void clearFrontend() override; + void restore() override; + + void enable(ErrorString*) override; + void disable(ErrorString*) override; + void setSamplingInterval(ErrorString*, int) override; + void start(ErrorString*) override; + void stop(ErrorString*, RefPtr<TypeBuilder::Profiler::CPUProfile>&) override; + + void consoleProfile(const String& title) override; + void consoleProfileEnd(const String& title) override; + + void idleStarted(); + void idleFinished(); + +private: + void stop(ErrorString*, RefPtr<TypeBuilder::Profiler::CPUProfile>*); + String nextProfileId(); + + void startProfiling(const String& title); + PassRefPtr<TypeBuilder::Profiler::CPUProfile> stopProfiling(const String& title, bool serialize); + + bool isRecording() const; + + v8::Isolate* m_isolate; + InspectorState* m_state; + InspectorFrontend::Profiler* m_frontend; + bool m_enabled; + bool m_recordingCPUProfile; + class ProfileDescriptor; + Vector<ProfileDescriptor> m_startedProfiles; + String m_frontendInitiatedProfileId; +}; + +} // namespace blink + + +#endif // !defined(V8ProfilerAgentImpl_h)
diff --git a/third_party/WebKit/Source/core/layout/ImageQualityControllerTest.cpp b/third_party/WebKit/Source/core/layout/ImageQualityControllerTest.cpp index 41fcfd9..bd1fbe0 100644 --- a/third_party/WebKit/Source/core/layout/ImageQualityControllerTest.cpp +++ b/third_party/WebKit/Source/core/layout/ImageQualityControllerTest.cpp
@@ -107,7 +107,7 @@ RefPtr<TestImageLowQuality> testImage = adoptRef(new TestImageLowQuality); OwnPtr<PaintController> paintController = PaintController::create(); - GraphicsContext context(paintController.get()); + GraphicsContext context(*paintController); EXPECT_EQ(InterpolationMedium, controller()->chooseInterpolationQuality(&context, img, testImage.get(), testImage.get(), LayoutSize(1, 1))); } @@ -135,7 +135,7 @@ RefPtr<TestImageLowQuality> testImage = adoptRef(new TestImageLowQuality); OwnPtr<PaintController> paintController = PaintController::create(); - GraphicsContext context(paintController.get()); + GraphicsContext context(*paintController); // Start a resize document().frame()->view()->willStartLiveResize(); @@ -167,7 +167,7 @@ RefPtr<TestImageLowQuality> testImage = adoptRef(new TestImageLowQuality); OwnPtr<PaintController> paintController = PaintController::create(); - GraphicsContext context(paintController.get()); + GraphicsContext context(*paintController); // Paint once. This will kick off a timer to see if we resize it during that timer's execution. EXPECT_EQ(InterpolationMedium, controller()->chooseInterpolationQuality(&context, img, testImage.get(), testImage.get(), LayoutSize(2, 2))); @@ -192,7 +192,7 @@ RefPtr<TestImageLowQuality> testImage = adoptRef(new TestImageLowQuality); OwnPtr<PaintController> paintController = PaintController::create(); - GraphicsContext context(paintController.get()); + GraphicsContext context(*paintController); // Paint once. This will kick off a timer to see if we resize it during that timer's execution. EXPECT_EQ(InterpolationMedium, controller()->chooseInterpolationQuality(&context, img, testImage.get(), testImage.get(), LayoutSize(2, 2)));
diff --git a/third_party/WebKit/Source/core/layout/LayoutReplaced.cpp b/third_party/WebKit/Source/core/layout/LayoutReplaced.cpp index 53a2b872..329b4205 100644 --- a/third_party/WebKit/Source/core/layout/LayoutReplaced.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutReplaced.cpp
@@ -125,6 +125,7 @@ return false; LayoutRect paintRect(visualOverflowRect()); + paintRect.unite(localSelectionRect()); paintRect.moveBy(paintOffset + location()); // Early exit if the element touches the edges.
diff --git a/third_party/WebKit/Source/core/loader/EmptyClients.h b/third_party/WebKit/Source/core/loader/EmptyClients.h index 1048eae..6414307 100644 --- a/third_party/WebKit/Source/core/loader/EmptyClients.h +++ b/third_party/WebKit/Source/core/loader/EmptyClients.h
@@ -148,7 +148,7 @@ void openFileChooser(LocalFrame*, PassRefPtr<FileChooser>) override; - void setCursor(const Cursor&) override {} + void setCursor(const Cursor&, LocalFrame* localRoot) override {} Cursor lastSetCursorForTesting() const override { return pointerCursor(); } void attachRootGraphicsLayer(GraphicsLayer*, LocalFrame* localRoot) override {}
diff --git a/third_party/WebKit/Source/core/page/ChromeClient.h b/third_party/WebKit/Source/core/page/ChromeClient.h index 9146f69..b474502 100644 --- a/third_party/WebKit/Source/core/page/ChromeClient.h +++ b/third_party/WebKit/Source/core/page/ChromeClient.h
@@ -140,7 +140,7 @@ // Methods used by HostWindow. virtual WebScreenInfo screenInfo() const = 0; - virtual void setCursor(const Cursor&) = 0; + virtual void setCursor(const Cursor&, LocalFrame* localRoot) = 0; // End methods used by HostWindow. virtual Cursor lastSetCursorForTesting() const = 0;
diff --git a/third_party/WebKit/Source/core/paint/LayerClipRecorderTest.cpp b/third_party/WebKit/Source/core/paint/LayerClipRecorderTest.cpp index 25d92c4..5f07cd0 100644 --- a/third_party/WebKit/Source/core/paint/LayerClipRecorderTest.cpp +++ b/third_party/WebKit/Source/core/paint/LayerClipRecorderTest.cpp
@@ -60,7 +60,7 @@ TEST_F(LayerClipRecorderTest, Single) { - GraphicsContext context(&rootPaintController()); + GraphicsContext context(rootPaintController()); LayoutRect bound = layoutView().viewRect(); EXPECT_EQ((size_t)0, rootPaintController().displayItemList().size()); @@ -74,7 +74,7 @@ TEST_F(LayerClipRecorderTest, Empty) { - GraphicsContext context(&rootPaintController()); + GraphicsContext context(rootPaintController()); EXPECT_EQ((size_t)0, rootPaintController().displayItemList().size()); drawEmptyClip(context, layoutView(), PaintPhaseForeground);
diff --git a/third_party/WebKit/Source/core/paint/LayoutObjectDrawingRecorderTest.cpp b/third_party/WebKit/Source/core/paint/LayoutObjectDrawingRecorderTest.cpp index 077919f..9f41d0ff 100644 --- a/third_party/WebKit/Source/core/paint/LayoutObjectDrawingRecorderTest.cpp +++ b/third_party/WebKit/Source/core/paint/LayoutObjectDrawingRecorderTest.cpp
@@ -41,7 +41,7 @@ TEST_F(LayoutObjectDrawingRecorderTest, Nothing) { - GraphicsContext context(&rootPaintController()); + GraphicsContext context(rootPaintController()); LayoutRect bound = layoutView().viewRect(); EXPECT_EQ((size_t)0, rootPaintController().displayItemList().size()); @@ -54,7 +54,7 @@ TEST_F(LayoutObjectDrawingRecorderTest, Rect) { - GraphicsContext context(&rootPaintController()); + GraphicsContext context(rootPaintController()); LayoutRect bound = layoutView().viewRect(); drawRect(context, layoutView(), PaintPhaseForeground, bound); rootPaintController().commitNewDisplayItems(); @@ -64,7 +64,7 @@ TEST_F(LayoutObjectDrawingRecorderTest, Cached) { - GraphicsContext context(&rootPaintController()); + GraphicsContext context(rootPaintController()); LayoutRect bound = layoutView().viewRect(); drawNothing(context, layoutView(), PaintPhaseBlockBackground, bound); drawRect(context, layoutView(), PaintPhaseForeground, bound); @@ -94,7 +94,7 @@ controller.invalidateAll(); { // Draw some things which will produce a non-null picture. - GraphicsContext context(&controller); + GraphicsContext context(controller); LayoutObjectDrawingRecorder recorder( context, layoutObject, DisplayItem::BoxDecorationBackground, bounds, LayoutPoint()); context.drawRect(enclosedIntRect(FloatRect(bounds))); @@ -123,7 +123,7 @@ { RuntimeEnabledFeatures::setSlimmingPaintOffsetCachingEnabled(true); - GraphicsContext context(&rootPaintController()); + GraphicsContext context(rootPaintController()); LayoutRect bounds = layoutView().viewRect(); LayoutPoint paintOffset(1, 2);
diff --git a/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.cpp b/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.cpp index 9af8907..48187b1 100644 --- a/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.cpp +++ b/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.cpp
@@ -25,7 +25,7 @@ LayoutObject& divLayoutObject = *document().body()->firstChild()->layoutObject(); InlineTextBox& textInlineBox = *toLayoutText(div.firstChild()->layoutObject())->firstTextBox(); - GraphicsContext context(&rootPaintController()); + GraphicsContext context(rootPaintController()); PaintLayerPaintingInfo paintingInfo(&rootLayer, LayoutRect(0, 0, 800, 600), GlobalPaintNormalPhase, LayoutSize()); PaintLayerPainter(rootLayer).paintLayerContents(&context, paintingInfo, PaintLayerPaintingCompositingAllPhases); rootPaintController().commitNewDisplayItems(); @@ -58,7 +58,7 @@ InlineTextBox& firstTextBox = *text.firstTextBox(); DisplayItemClient firstTextBoxDisplayItemClient = firstTextBox.displayItemClient(); - GraphicsContext context(&rootPaintController()); + GraphicsContext context(rootPaintController()); PaintLayerPaintingInfo paintingInfo(&rootLayer, LayoutRect(0, 0, 800, 600), GlobalPaintNormalPhase, LayoutSize()); PaintLayerPainter(rootLayer).paintLayerContents(&context, paintingInfo, PaintLayerPaintingCompositingAllPhases); rootPaintController().commitNewDisplayItems();
diff --git a/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.h b/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.h index 7dd39bc9..43952c1 100644 --- a/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.h +++ b/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.h
@@ -17,7 +17,7 @@ class PaintControllerPaintTest : public RenderingTest { public: PaintControllerPaintTest() - : m_originalSlimmingPaintSubsequenceCachingEnabled(RuntimeEnabledFeatures::slimmingPaintSubsequenceCachingEnabled()) + : m_originalSlimmingPaintSynchronizedPaintingEnabled(RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEnabled()) , m_originalSlimmingPaintOffsetCachingEnabled(RuntimeEnabledFeatures::slimmingPaintOffsetCachingEnabled()) { } @@ -30,14 +30,16 @@ { RenderingTest::SetUp(); enableCompositing(); + GraphicsLayer::setDrawDebugRedFillForTesting(false); } void TearDown() override { - RuntimeEnabledFeatures::setSlimmingPaintSubsequenceCachingEnabled(m_originalSlimmingPaintSubsequenceCachingEnabled); + RuntimeEnabledFeatures::setSlimmingPaintSynchronizedPaintingEnabled(m_originalSlimmingPaintSynchronizedPaintingEnabled); RuntimeEnabledFeatures::setSlimmingPaintOffsetCachingEnabled(m_originalSlimmingPaintOffsetCachingEnabled); + GraphicsLayer::setDrawDebugRedFillForTesting(true); } - bool m_originalSlimmingPaintSubsequenceCachingEnabled; + bool m_originalSlimmingPaintSynchronizedPaintingEnabled; bool m_originalSlimmingPaintOffsetCachingEnabled; };
diff --git a/third_party/WebKit/Source/core/paint/PaintLayer.cpp b/third_party/WebKit/Source/core/paint/PaintLayer.cpp index 36bfa4d4..94ca11e 100644 --- a/third_party/WebKit/Source/core/paint/PaintLayer.cpp +++ b/third_party/WebKit/Source/core/paint/PaintLayer.cpp
@@ -2716,6 +2716,13 @@ } } +void PaintLayer::clearNeedsRepaintRecursively() +{ + for (PaintLayer* child = firstChild(); child; child = child->nextSibling()) + child->clearNeedsRepaintRecursively(); + m_needsRepaint = false; +} + ObjectPaintProperties& PaintLayer::mutablePaintProperties() { ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled());
diff --git a/third_party/WebKit/Source/core/paint/PaintLayer.h b/third_party/WebKit/Source/core/paint/PaintLayer.h index e825290..5be2384 100644 --- a/third_party/WebKit/Source/core/paint/PaintLayer.h +++ b/third_party/WebKit/Source/core/paint/PaintLayer.h
@@ -598,7 +598,7 @@ bool needsRepaint() const { return m_needsRepaint; } void setNeedsRepaint(); - void clearNeedsRepaint() { m_needsRepaint = false; } + void clearNeedsRepaintRecursively(); IntSize previousScrollOffsetAccumulationForPainting() const { return m_previousScrollOffsetAccumulationForPainting; } void setPreviousScrollOffsetAccumulationForPainting(const IntSize& s) { m_previousScrollOffsetAccumulationForPainting = s; }
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp b/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp index 2069581..e9cb238 100644 --- a/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp +++ b/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp
@@ -58,17 +58,6 @@ PaintLayerPainter::PaintResult PaintLayerPainter::paintLayer(GraphicsContext* context, const PaintLayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags) { - PaintResult result = paintLayerInternal(context, paintingInfo, paintFlags); - // TODO(wangxianzhu): We may paint a layer multiple times with different flags. - // The following ensures the flag is only cleared once after the last painting. - // This is fragile but is temporary for spv1. - if ((paintFlags & PaintLayerPaintingCompositingForegroundPhase) || m_paintLayer.layoutObject()->isLayoutView()) - m_paintLayer.clearNeedsRepaint(); - return result; -} - -PaintLayerPainter::PaintResult PaintLayerPainter::paintLayerInternal(GraphicsContext* context, const PaintLayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags) -{ // https://code.google.com/p/chromium/issues/detail?id=343772 DisableCompositingQueryAsserts disabler; @@ -122,7 +111,7 @@ } localPaintFlags |= PaintLayerPaintingCompositingAllPhases; - if (paintLayerContentsInternal(context, paintingInfo, localPaintFlags, fragmentPolicy) == MaybeNotFullyPainted) + if (paintLayerContents(context, paintingInfo, localPaintFlags, fragmentPolicy) == MaybeNotFullyPainted) result = MaybeNotFullyPainted; return result; @@ -190,18 +179,7 @@ GraphicsContext* m_context; }; -PaintLayerPainter::PaintResult PaintLayerPainter::paintLayerContents(GraphicsContext* context, const PaintLayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags, FragmentPolicy fragmentPolicy) -{ - PaintResult result = paintLayerContentsInternal(context, paintingInfo, paintFlags, fragmentPolicy); - // TODO(wangxianzhu): We may paint a layer multiple times with different flags. - // The following ensures the flag is only cleared once after the last painting. - // This is fragile but is temporary for spv1. - if (paintFlags & PaintLayerPaintingCompositingForegroundPhase) - m_paintLayer.clearNeedsRepaint(); - return result; -} - -PaintLayerPainter::PaintResult PaintLayerPainter::paintLayerContentsInternal(GraphicsContext* context, const PaintLayerPaintingInfo& paintingInfoArg, PaintLayerFlags paintFlags, FragmentPolicy fragmentPolicy) +PaintLayerPainter::PaintResult PaintLayerPainter::paintLayerContents(GraphicsContext* context, const PaintLayerPaintingInfo& paintingInfoArg, PaintLayerFlags paintFlags, FragmentPolicy fragmentPolicy) { ASSERT(m_paintLayer.isSelfPaintingLayer() || m_paintLayer.hasSelfPaintingLayerDescendant()); ASSERT(!(paintFlags & PaintLayerAppliedTransform));
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerPainter.h b/third_party/WebKit/Source/core/paint/PaintLayerPainter.h index 26f4758..05095cc 100644 --- a/third_party/WebKit/Source/core/paint/PaintLayerPainter.h +++ b/third_party/WebKit/Source/core/paint/PaintLayerPainter.h
@@ -46,8 +46,6 @@ private: enum ClipState { HasNotClipped, HasClipped }; - PaintResult paintLayerInternal(GraphicsContext*, const PaintLayerPaintingInfo&, PaintLayerFlags); - PaintResult paintLayerContentsInternal(GraphicsContext*, const PaintLayerPaintingInfo&, PaintLayerFlags, FragmentPolicy = AllowMultipleFragments); PaintResult paintLayerContentsAndReflection(GraphicsContext*, const PaintLayerPaintingInfo&, PaintLayerFlags, FragmentPolicy = AllowMultipleFragments); PaintResult paintLayerWithTransform(GraphicsContext*, const PaintLayerPaintingInfo&, PaintLayerFlags); PaintResult paintFragmentByApplyingTransform(GraphicsContext*, const PaintLayerPaintingInfo&, PaintLayerFlags, const LayoutPoint& fragmentTranslation);
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerPainterTest.cpp b/third_party/WebKit/Source/core/paint/PaintLayerPainterTest.cpp index c7e5fd91..b5f81f7 100644 --- a/third_party/WebKit/Source/core/paint/PaintLayerPainterTest.cpp +++ b/third_party/WebKit/Source/core/paint/PaintLayerPainterTest.cpp
@@ -26,7 +26,7 @@ TEST_P(PaintLayerPainterTest, CachedSubsequence) { - RuntimeEnabledFeatures::setSlimmingPaintSubsequenceCachingEnabled(true); + RuntimeEnabledFeatures::setSlimmingPaintSynchronizedPaintingEnabled(true); setBodyInnerHTML( "<div id='container1' style='position: relative; z-index: 1; width: 200px; height: 200px; background-color: blue'>" @@ -47,11 +47,6 @@ PaintLayer& container2Layer = *toLayoutBoxModelObject(container2).layer(); LayoutObject& content2 = *document().getElementById("content2")->layoutObject(); - GraphicsContext context(&rootPaintController()); - PaintLayerPaintingInfo paintingInfo(&rootLayer, LayoutRect(0, 0, 800, 600), GlobalPaintNormalPhase, LayoutSize()); - PaintLayerPainter(rootLayer).paintLayerContents(&context, paintingInfo, PaintLayerPaintingCompositingAllPhases); - rootPaintController().commitNewDisplayItems(); - if (rootLayerScrolls) { EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 11, TestDisplayItem(layoutView(), backgroundType), @@ -84,73 +79,6 @@ toHTMLElement(content1.node())->setAttribute(HTMLNames::styleAttr, "position: absolute; width: 100px; height: 100px; background-color: green"); document().view()->updateAllLifecyclePhases(); - PaintLayerPainter(rootLayer).paintLayerContents(&context, paintingInfo, PaintLayerPaintingCompositingAllPhases); - - if (rootLayerScrolls) { - EXPECT_DISPLAY_LIST(rootPaintController().newDisplayItemList(), 9, - TestDisplayItem(layoutView(), cachedBackgroundType), - TestDisplayItem(rootLayer, subsequenceType), - TestDisplayItem(container1, cachedBackgroundType), - TestDisplayItem(container1Layer, subsequenceType), - TestDisplayItem(content1, backgroundType), - TestDisplayItem(container1Layer, endSubsequenceType), - TestDisplayItem(container2, cachedBackgroundType), - TestDisplayItem(container2Layer, cachedSubsequenceType), - TestDisplayItem(rootLayer, endSubsequenceType)); - } else { - EXPECT_DISPLAY_LIST(rootPaintController().newDisplayItemList(), 11, - TestDisplayItem(layoutView(), cachedBackgroundType), - TestDisplayItem(rootLayer, subsequenceType), - TestDisplayItem(htmlLayer, subsequenceType), - TestDisplayItem(container1, cachedBackgroundType), - TestDisplayItem(container1Layer, subsequenceType), - TestDisplayItem(content1, backgroundType), - TestDisplayItem(container1Layer, endSubsequenceType), - TestDisplayItem(container2, cachedBackgroundType), - TestDisplayItem(container2Layer, cachedSubsequenceType), - TestDisplayItem(htmlLayer, endSubsequenceType), - TestDisplayItem(rootLayer, endSubsequenceType)); - } - - rootPaintController().commitNewDisplayItems(); - - if (rootLayerScrolls) { - EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 11, - TestDisplayItem(layoutView(), backgroundType), - TestDisplayItem(rootLayer, subsequenceType), - TestDisplayItem(container1, backgroundType), - TestDisplayItem(container1Layer, subsequenceType), - TestDisplayItem(content1, backgroundType), - TestDisplayItem(container1Layer, endSubsequenceType), - TestDisplayItem(container2, backgroundType), - TestDisplayItem(container2Layer, subsequenceType), - TestDisplayItem(content2, backgroundType), - TestDisplayItem(container2Layer, endSubsequenceType), - TestDisplayItem(rootLayer, endSubsequenceType)); - } else { - EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 13, - TestDisplayItem(layoutView(), backgroundType), - TestDisplayItem(rootLayer, subsequenceType), - TestDisplayItem(htmlLayer, subsequenceType), - TestDisplayItem(container1, backgroundType), - TestDisplayItem(container1Layer, subsequenceType), - TestDisplayItem(content1, backgroundType), - TestDisplayItem(container1Layer, endSubsequenceType), - TestDisplayItem(container2, backgroundType), - TestDisplayItem(container2Layer, subsequenceType), - TestDisplayItem(content2, backgroundType), - TestDisplayItem(container2Layer, endSubsequenceType), - TestDisplayItem(htmlLayer, endSubsequenceType), - TestDisplayItem(rootLayer, endSubsequenceType)); - } - - // Repeated painting should just generate the root cached subsequence. - PaintLayerPainter(rootLayer).paintLayerContents(&context, paintingInfo, PaintLayerPaintingCompositingAllPhases); - EXPECT_DISPLAY_LIST(rootPaintController().newDisplayItemList(), 2, - TestDisplayItem(layoutView(), cachedBackgroundType), - TestDisplayItem(rootLayer, cachedSubsequenceType)); - - rootPaintController().commitNewDisplayItems(); if (rootLayerScrolls) { EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 11, @@ -185,7 +113,7 @@ TEST_P(PaintLayerPainterTest, CachedSubsequenceOnInterestRectChange) { - RuntimeEnabledFeatures::setSlimmingPaintSubsequenceCachingEnabled(true); + RuntimeEnabledFeatures::setSlimmingPaintSynchronizedPaintingEnabled(true); setBodyInnerHTML( "<div id='container1' style='position: relative; z-index: 1; width: 200px; height: 200px; background-color: blue'>" @@ -213,11 +141,8 @@ PaintLayer& container3Layer = *toLayoutBoxModelObject(container3).layer(); LayoutObject& content3 = *document().getElementById("content3")->layoutObject(); - document().view()->updateAllLifecyclePhases(); - GraphicsContext context(&rootPaintController()); - PaintLayerPaintingInfo paintingInfo(&rootLayer, LayoutRect(0, 0, 400, 300), GlobalPaintNormalPhase, LayoutSize()); - PaintLayerPainter(rootLayer).paintLayerContents(&context, paintingInfo, PaintLayerPaintingCompositingAllPhases); - rootPaintController().commitNewDisplayItems(); + LayoutRect interestRect(0, 0, 400, 300); + document().view()->updateAllLifecyclePhases(&interestRect); // Container1 is fully in the interest rect; // Container2 is partly (including its stacking chidren) in the interest rect; @@ -261,43 +186,14 @@ TestDisplayItem(rootLayer, endSubsequenceType)); } + LayoutRect newInterestRect(0, 100, 300, 300); + document().view()->updateAllLifecyclePhases(&newInterestRect); + // Container1 becomes partly in the interest rect, but uses cached subsequence // because it was fully painted before; // Container2's intersection with the interest rect changes; // Content2b is out of the interest rect and outputs nothing; // Container3 becomes out of the interest rect and outputs nothing. - PaintLayerPaintingInfo paintingInfo1(&rootLayer, LayoutRect(0, 100, 300, 300), GlobalPaintNormalPhase, LayoutSize()); - PaintLayerPainter(rootLayer).paintLayerContents(&context, paintingInfo1, PaintLayerPaintingCompositingAllPhases); - - if (rootLayerScrolls) { - EXPECT_DISPLAY_LIST(rootPaintController().newDisplayItemList(), 9, - TestDisplayItem(layoutView(), cachedBackgroundType), - TestDisplayItem(rootLayer, subsequenceType), - TestDisplayItem(container1, cachedBackgroundType), - TestDisplayItem(container1Layer, cachedSubsequenceType), - TestDisplayItem(container2, cachedBackgroundType), - TestDisplayItem(container2Layer, subsequenceType), - TestDisplayItem(content2a, cachedBackgroundType), - TestDisplayItem(container2Layer, endSubsequenceType), - TestDisplayItem(rootLayer, endSubsequenceType)); - - } else { - EXPECT_DISPLAY_LIST(rootPaintController().newDisplayItemList(), 11, - TestDisplayItem(layoutView(), cachedBackgroundType), - TestDisplayItem(rootLayer, subsequenceType), - TestDisplayItem(htmlLayer, subsequenceType), - TestDisplayItem(container1, cachedBackgroundType), - TestDisplayItem(container1Layer, cachedSubsequenceType), - TestDisplayItem(container2, cachedBackgroundType), - TestDisplayItem(container2Layer, subsequenceType), - TestDisplayItem(content2a, cachedBackgroundType), - TestDisplayItem(container2Layer, endSubsequenceType), - TestDisplayItem(htmlLayer, endSubsequenceType), - TestDisplayItem(rootLayer, endSubsequenceType)); - } - - rootPaintController().commitNewDisplayItems(); - if (rootLayerScrolls) { EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 11, TestDisplayItem(layoutView(), backgroundType),
diff --git a/third_party/WebKit/Source/core/paint/SVGFilterPainter.cpp b/third_party/WebKit/Source/core/paint/SVGFilterPainter.cpp index 5cc82e8..ddd2b52b 100644 --- a/third_party/WebKit/Source/core/paint/SVGFilterPainter.cpp +++ b/third_party/WebKit/Source/core/paint/SVGFilterPainter.cpp
@@ -28,7 +28,7 @@ // Create a new context so the contents of the filter can be drawn and cached. m_paintController = PaintController::create(); - m_context = adoptPtr(new GraphicsContext(m_paintController.get())); + m_context = adoptPtr(new GraphicsContext(*m_paintController)); context = m_context.get(); filterData->m_state = FilterData::RecordingContent;
diff --git a/third_party/WebKit/Source/core/paint/TableCellPainterTest.cpp b/third_party/WebKit/Source/core/paint/TableCellPainterTest.cpp index 9b38f56..a1f9120 100644 --- a/third_party/WebKit/Source/core/paint/TableCellPainterTest.cpp +++ b/third_party/WebKit/Source/core/paint/TableCellPainterTest.cpp
@@ -31,7 +31,7 @@ LayoutObject& cell1 = *document().getElementById("cell1")->layoutObject(); LayoutObject& cell2 = *document().getElementById("cell2")->layoutObject(); - GraphicsContext context(&rootPaintController()); + GraphicsContext context(rootPaintController()); PaintLayerPaintingInfo paintingInfo(&rootLayer, LayoutRect(0, 0, 200, 200), GlobalPaintNormalPhase, LayoutSize()); PaintLayerPainter(rootLayer).paintLayerContents(&context, paintingInfo, PaintLayerPaintingCompositingAllPhases); rootPaintController().commitNewDisplayItems();
diff --git a/third_party/WebKit/Source/devtools/devtools.gypi b/third_party/WebKit/Source/devtools/devtools.gypi index 74cbe9c..74959fc 100644 --- a/third_party/WebKit/Source/devtools/devtools.gypi +++ b/third_party/WebKit/Source/devtools/devtools.gypi
@@ -574,7 +574,7 @@ 'front_end/script_formatter_worker/ScriptFormatterWorker.js', ], 'devtools_settings_js_files': [ - 'front_end/settings/EditFileSystemDialog.js', + 'front_end/settings/EditFileSystemView.js', 'front_end/settings/FrameworkBlackboxSettingsTab.js', 'front_end/settings/SettingsScreen.js', ],
diff --git a/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilitySidebarView.js b/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilitySidebarView.js index 61a8cd4..9dd59f6 100644 --- a/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilitySidebarView.js +++ b/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilitySidebarView.js
@@ -494,7 +494,8 @@ */ appendRelationshipValueElement: function(value) { - var deferredNode = new WebInspector.DeferredDOMNode(this._target, value.relatedNodeValue.backendNodeId); + var relatedNode = value.relatedNodes[0]; + var deferredNode = new WebInspector.DeferredDOMNode(this._target, relatedNode.backendNodeId); var valueElement = createElement("span"); /** @@ -503,8 +504,8 @@ function onNodeResolved(node) { valueElement.appendChild(WebInspector.DOMPresentationUtils.linkifyNodeReference(node)); - if (value.relatedNodeValue.text) { - var textElement = WebInspector.AccessibilitySidebarView.createSimpleValueElement(AccessibilityAgent.AXValueType.ComputedString, value.relatedNodeValue.text); + if (relatedNode.text) { + var textElement = WebInspector.AccessibilitySidebarView.createSimpleValueElement(AccessibilityAgent.AXValueType.ComputedString, relatedNode.text); valueElement.appendChild(textElement); } } @@ -518,7 +519,7 @@ */ appendRelatedNodeListValueElement: function(value) { - var relatedNodes = value.relatedNodeArrayValue; + var relatedNodes = value.relatedNodes; var numNodes = relatedNodes.length; var valueElement; if (value.type === AccessibilityAgent.AXValueType.IdrefList) {
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/ElementsTreeElement.js b/third_party/WebKit/Source/devtools/front_end/elements/ElementsTreeElement.js index 123fa1e..0909a0c 100644 --- a/third_party/WebKit/Source/devtools/front_end/elements/ElementsTreeElement.js +++ b/third_party/WebKit/Source/devtools/front_end/elements/ElementsTreeElement.js
@@ -261,11 +261,9 @@ if (!this.selectionElement) { this.selectionElement = createElement("div"); - this.selectionElement.className = "selection selected"; + this.selectionElement.className = "selection fill"; listItemElement.insertBefore(this.selectionElement, listItemElement.firstChild); } - - this.selectionElement.style.height = listItemElement.offsetHeight + "px"; }, /** @@ -1100,8 +1098,19 @@ updateDecorations: function() { + var treeElement = this.parent; + var depth = 0; + while (treeElement != null) { + depth++; + treeElement = treeElement.parent; + } + + /** Keep it in sync with elementsTreeOutline.css **/ + this._gutterContainer.style.left = (-12 * (depth - 2) - (this.isExpandable() ? 1 : 12)) + "px"; + if (this.isClosingTag()) return; + var node = this._node; if (node.nodeType() !== Node.ELEMENT_NODE) return;
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/ElementsTreeOutline.js b/third_party/WebKit/Source/devtools/front_end/elements/ElementsTreeOutline.js index 5d399ba6..e3345a7 100644 --- a/third_party/WebKit/Source/devtools/front_end/elements/ElementsTreeOutline.js +++ b/third_party/WebKit/Source/devtools/front_end/elements/ElementsTreeOutline.js
@@ -1790,7 +1790,7 @@ WebInspector.ElementsTreeOutline.ShortcutTreeElement = function(nodeShortcut) { TreeElement.call(this, ""); - this.listItemElement.createChild("div", "selection"); + this.listItemElement.createChild("div", "selection fill"); var title = this.listItemElement.createChild("span", "elements-tree-shortcut-title"); var text = nodeShortcut.nodeName.toLowerCase(); if (nodeShortcut.nodeType === Node.ELEMENT_NODE)
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/elementsTreeOutline.css b/third_party/WebKit/Source/devtools/front_end/elements/elementsTreeOutline.css index a4967ea..5c4d93f7 100644 --- a/third_party/WebKit/Source/devtools/front_end/elements/elementsTreeOutline.css +++ b/third_party/WebKit/Source/devtools/front_end/elements/elementsTreeOutline.css
@@ -11,13 +11,16 @@ } .elements-disclosure li { + /** Keep margin-left & padding-left in sync with ElementsTreeElements.updateDecorators **/ padding: 0 0 0 14px; margin-top: 1px; margin-left: -2px; word-wrap: break-word; + position: relative; } .elements-disclosure li.parent { + /** Keep it in sync with ElementsTreeElements.updateDecorators **/ margin-left: -13px; } @@ -54,11 +57,8 @@ .elements-disclosure li .selection { display: none; - position: absolute; - left: 0; - right: 0; - height: 15px; z-index: -1; + margin-left: -10000px; } .elements-disclosure li.hovered:not(.selected) .selection { @@ -80,6 +80,7 @@ .elements-disclosure ol { list-style-type: none; + /** Keep it in sync with ElementsTreeElements.updateDecorators **/ -webkit-padding-start: 12px; margin: 0; }
diff --git a/third_party/WebKit/Source/devtools/front_end/inspectorStyle.css b/third_party/WebKit/Source/devtools/front_end/inspectorStyle.css index ecf126de..27e1017a 100644 --- a/third_party/WebKit/Source/devtools/front_end/inspectorStyle.css +++ b/third_party/WebKit/Source/devtools/front_end/inspectorStyle.css
@@ -135,6 +135,10 @@ margin: 0; } +.outline-disclosure li { + position: relative; +} + .outline-disclosure li.hovered:not(.selected) .selection { display: block; left: 3px; @@ -145,11 +149,8 @@ .outline-disclosure li .selection { display: none; - position: absolute; - left: 0; - right: 0; - height: 15px; z-index: -1; + margin-left: -10000px; } .outline-disclosure li.selected .selection { @@ -192,7 +193,6 @@ margin-top: 1px; text-overflow: ellipsis; white-space: nowrap; - overflow: hidden; } ol.outline-disclosure:focus li.selected { @@ -608,4 +608,4 @@ box-shadow: 0 1px 0 rgba(80, 80, 80, 0.08), inset 0 1px 2px rgba(255, 255, 255, 0.75); color: #aaa; -} \ No newline at end of file +}
diff --git a/third_party/WebKit/Source/devtools/front_end/resources/FileSystemView.js b/third_party/WebKit/Source/devtools/front_end/resources/FileSystemView.js index dc6786e..d372176 100644 --- a/third_party/WebKit/Source/devtools/front_end/resources/FileSystemView.js +++ b/third_party/WebKit/Source/devtools/front_end/resources/FileSystemView.js
@@ -128,7 +128,7 @@ */ onattach: function() { - var selection = this.listItemElement.createChild("div", "selection"); + var selection = this.listItemElement.createChild("div", "selection fill"); this.listItemElement.insertBefore(selection, this.listItemElement.firstChild); },
diff --git a/third_party/WebKit/Source/devtools/front_end/resources/ResourcesPanel.js b/third_party/WebKit/Source/devtools/front_end/resources/ResourcesPanel.js index f909238..60d574f 100644 --- a/third_party/WebKit/Source/devtools/front_end/resources/ResourcesPanel.js +++ b/third_party/WebKit/Source/devtools/front_end/resources/ResourcesPanel.js
@@ -853,7 +853,7 @@ this.listItemElement.classList.add(this._iconClasses[i]); } - this.listItemElement.createChild("div", "selection"); + this.listItemElement.createChild("div", "selection fill"); if (!this._noIcon) this.imageElement = this.listItemElement.createChild("img", "icon");
diff --git a/third_party/WebKit/Source/devtools/front_end/settings/EditFileSystemDialog.js b/third_party/WebKit/Source/devtools/front_end/settings/EditFileSystemView.js similarity index 93% rename from third_party/WebKit/Source/devtools/front_end/settings/EditFileSystemDialog.js rename to third_party/WebKit/Source/devtools/front_end/settings/EditFileSystemView.js index de2647b..ae658b8 100644 --- a/third_party/WebKit/Source/devtools/front_end/settings/EditFileSystemDialog.js +++ b/third_party/WebKit/Source/devtools/front_end/settings/EditFileSystemView.js
@@ -33,16 +33,12 @@ * @extends {WebInspector.VBox} * @param {string} fileSystemPath */ -WebInspector.EditFileSystemDialog = function(fileSystemPath) +WebInspector.EditFileSystemView = function(fileSystemPath) { WebInspector.VBox.call(this); this.element.classList.add("dialog-contents", "settings-dialog", "settings-tab"); this._fileSystemPath = fileSystemPath; - var header = this.element.createChild("div", "header"); - var headerText = header.createChild("span"); - headerText.textContent = WebInspector.UIString("Edit file system"); - var contents = this.element.createChild("div", "contents"); WebInspector.fileSystemMapping.addEventListener(WebInspector.FileSystemMapping.Events.FileMappingAdded, this._fileMappingAdded, this); @@ -77,7 +73,7 @@ this._addMappingRow(entry); } - blockHeader = contents.createChild("div", "block-header"); + blockHeader = contents.createChild("div", "block-header excluded-folders-header"); blockHeader.textContent = WebInspector.UIString("Excluded folders"); this._excludedFolderListSection = contents.createChild("div", "section excluded-folders-section"); this._excludedFolderListContainer = this._excludedFolderListSection.createChild("div", "settings-list-container"); @@ -95,21 +91,17 @@ this.element.tabIndex = 0; this._hasMappingChanges = false; - - this._dialog = new WebInspector.Dialog(); - this._dialog.setWrapsContent(true); - this._dialog.setMaxSize(new Size(600, 600)); - this._dialog.addCloseButton(); - this.show(this._dialog.element); - this._dialog.show(); } -WebInspector.EditFileSystemDialog.show = function(fileSystemPath) -{ - new WebInspector.EditFileSystemDialog(fileSystemPath); -} +WebInspector.EditFileSystemView.prototype = { + dispose: function() + { + WebInspector.fileSystemMapping.removeEventListener(WebInspector.FileSystemMapping.Events.FileMappingAdded, this._fileMappingAdded, this); + WebInspector.fileSystemMapping.removeEventListener(WebInspector.FileSystemMapping.Events.FileMappingRemoved, this._fileMappingRemoved, this); + WebInspector.isolatedFileSystemManager.removeEventListener(WebInspector.IsolatedFileSystemManager.Events.ExcludedFolderAdded, this._excludedFolderAdded, this); + WebInspector.isolatedFileSystemManager.removeEventListener(WebInspector.IsolatedFileSystemManager.Events.ExcludedFolderRemoved, this._excludedFolderRemoved, this); + }, -WebInspector.EditFileSystemDialog.prototype = { _fileMappingAdded: function(event) { var entry = /** @type {!WebInspector.FileSystemMapping.Entry} */ (event.data); @@ -125,8 +117,6 @@ delete this._entries[key]; if (this._fileMappingsList.itemForId(key)) this._fileMappingsList.removeItem(key); - if (this._dialog) - this._dialog.contentResized(); }, /** @@ -256,8 +246,6 @@ this._entries[key] = entry; var keys = Object.keys(this._entries).sort(); this._fileMappingsList.addItem(key, keys[keys.indexOf(key) + 1], !entry.configurable); - if (this._dialog) - this._dialog.contentResized(); }, /** @@ -350,8 +338,6 @@ // Insert configurable entries before non-configurable. var insertBefore = readOnly ? null : this._firstNonConfigurableExcludedFolder; this._excludedFolderList.addItem(readOnly ? WebInspector.UIString("%s (via .devtools)", path) : path, insertBefore, readOnly); - if (this._dialog) - this._dialog.contentResized(); }, /**
diff --git a/third_party/WebKit/Source/devtools/front_end/settings/SettingsScreen.js b/third_party/WebKit/Source/devtools/front_end/settings/SettingsScreen.js index ea7b2512..453815a5 100644 --- a/third_party/WebKit/Source/devtools/front_end/settings/SettingsScreen.js +++ b/third_party/WebKit/Source/devtools/front_end/settings/SettingsScreen.js
@@ -327,99 +327,47 @@ this._addFileSystemRowElement = this._fileSystemsSection.createChild("div"); this._addFileSystemRowElement.appendChild(createTextButton(WebInspector.UIString("Add folder\u2026"), this._addFileSystemClicked.bind(this))); - this._editFileSystemButton = createTextButton(WebInspector.UIString("Folder options\u2026"), this._editFileSystemClicked.bind(this)); - this._addFileSystemRowElement.appendChild(this._editFileSystemButton); - this._updateEditFileSystemButtonState(); + /** @type {!Map<string, !Element>} */ + this._elementByPath = new Map(); - this._reset(); + /** @type {!Map<string, !WebInspector.EditFileSystemView>} */ + this._mappingViewByPath = new Map(); + + var fileSystemPaths = WebInspector.isolatedFileSystemManager.fileSystemPaths(); + for (var i = 0; i < fileSystemPaths.length; ++i) + this._addItem(/** @type {!WebInspector.IsolatedFileSystem} */ (WebInspector.isolatedFileSystemManager.fileSystem(fileSystemPaths[i]))); } WebInspector.WorkspaceSettingsTab.prototype = { - wasShown: function() + /** + * @param {!WebInspector.IsolatedFileSystem} fileSystem + */ + _addItem: function(fileSystem) { - WebInspector.SettingsTab.prototype.wasShown.call(this); - this._reset(); - }, + var element = this._renderFileSystem(fileSystem); + this._elementByPath.set(fileSystem.path(), element); - _reset: function() - { - this._resetFileSystems(); - }, + this._fileSystemsListContainer.appendChild(element); - _resetFileSystems: function() - { - this._fileSystemsListContainer.removeChildren(); - var fileSystemPaths = WebInspector.isolatedFileSystemManager.fileSystemPaths(); - delete this._fileSystemsList; - - if (!fileSystemPaths.length) { - var noFileSystemsMessageElement = this._fileSystemsListContainer.createChild("div", "no-file-systems-message"); - noFileSystemsMessageElement.textContent = WebInspector.UIString("You have no file systems added."); - return; - } - - this._fileSystemsList = new WebInspector.SettingsList([{ id: "path" }], this._renderFileSystem.bind(this)); - this._fileSystemsList.element.classList.add("file-systems-list"); - this._fileSystemsList.addEventListener(WebInspector.SettingsList.Events.Selected, this._fileSystemSelected.bind(this)); - this._fileSystemsList.addEventListener(WebInspector.SettingsList.Events.Removed, this._fileSystemRemovedfromList.bind(this)); - this._fileSystemsList.addEventListener(WebInspector.SettingsList.Events.DoubleClicked, this._fileSystemDoubleClicked.bind(this)); - this._fileSystemsListContainer.appendChild(this._fileSystemsList.element); - for (var i = 0; i < fileSystemPaths.length; ++i) - this._fileSystemsList.addItem(fileSystemPaths[i]); - this._updateEditFileSystemButtonState(); - }, - - _updateEditFileSystemButtonState: function() - { - this._editFileSystemButton.disabled = !this._selectedFileSystemPath(); + var mappingView = new WebInspector.EditFileSystemView(fileSystem.path()); + this._mappingViewByPath.set(fileSystem.path(), mappingView); + mappingView.show(element); }, /** - * @param {!WebInspector.Event} event + * @param {!WebInspector.IsolatedFileSystem} fileSystem + * @return {!Element} */ - _fileSystemSelected: function(event) + _renderFileSystem: function(fileSystem) { - this._updateEditFileSystemButtonState(); - }, - - /** - * @param {!WebInspector.Event} event - */ - _fileSystemDoubleClicked: function(event) - { - var id = /** @type{?string} */ (event.data); - this._editFileSystem(id); - }, - - _editFileSystemClicked: function() - { - this._editFileSystem(this._selectedFileSystemPath()); - }, - - /** - * @param {?string} id - */ - _editFileSystem: function(id) - { - WebInspector.EditFileSystemDialog.show(id); - }, - - /** - * @param {!Element} columnElement - * @param {{id: string, placeholder: (string|undefined), options: (!Array.<string>|undefined)}} column - * @param {?string} id - */ - _renderFileSystem: function(columnElement, column, id) - { - if (!id) - return ""; - var fileSystemPath = id; - var textElement = columnElement.createChild("span", "list-column-text"); - var pathElement = textElement.createChild("span", "file-system-path"); + var element = createElementWithClass("div", "file-system-container"); + var fileSystemPath = fileSystem.path(); + var textElement = element.createChild("div", "file-system-header"); + var pathElement = textElement.createChild("div", "file-system-path"); pathElement.title = fileSystemPath; - const maxTotalPathLength = 55; - const maxFolderNameLength = 30; + const maxTotalPathLength = 75; + const maxFolderNameLength = 40; var lastIndexOfSlash = fileSystemPath.lastIndexOf(WebInspector.isWin() ? "\\" : "/"); var folderName = fileSystemPath.substr(lastIndexOfSlash + 1); @@ -427,22 +375,25 @@ folderPath = folderPath.trimMiddle(maxTotalPathLength - Math.min(maxFolderNameLength, folderName.length)); folderName = folderName.trimMiddle(maxFolderNameLength); + pathElement.createChild("span").textContent = WebInspector.UIString("Folder: "); + var folderPathElement = pathElement.createChild("span"); folderPathElement.textContent = folderPath; var nameElement = pathElement.createChild("span", "file-system-path-name"); nameElement.textContent = folderName; + + textElement.appendChild(createTextButton(WebInspector.UIString("Remove"), this._removeFileSystemClicked.bind(this, fileSystem))); + + return element; }, /** - * @param {!WebInspector.Event} event + * @param {!WebInspector.IsolatedFileSystem} fileSystem */ - _fileSystemRemovedfromList: function(event) + _removeFileSystemClicked: function(fileSystem) { - var id = /** @type{?string} */ (event.data); - if (!id) - return; - WebInspector.isolatedFileSystemManager.removeFileSystem(id); + WebInspector.isolatedFileSystemManager.removeFileSystem(fileSystem.path()); }, _addFileSystemClicked: function() @@ -453,25 +404,24 @@ _fileSystemAdded: function(event) { var fileSystem = /** @type {!WebInspector.IsolatedFileSystem} */ (event.data); - if (!this._fileSystemsList) - this._reset(); - else - this._fileSystemsList.addItem(fileSystem.path()); + this._addItem(fileSystem); }, _fileSystemRemoved: function(event) { var fileSystem = /** @type {!WebInspector.IsolatedFileSystem} */ (event.data); - if (this._fileSystemsList.itemForId(fileSystem.path())) - this._fileSystemsList.removeItem(fileSystem.path()); - if (!this._fileSystemsList.itemIds().length) - this._reset(); - this._updateEditFileSystemButtonState(); - }, - _selectedFileSystemPath: function() - { - return this._fileSystemsList ? this._fileSystemsList.selectedId() : null; + var mappingView = this._mappingViewByPath.get(fileSystem.path()); + if (mappingView) { + mappingView.dispose(); + this._mappingViewByPath.delete(fileSystem.path()); + } + + var element = this._elementByPath.get(fileSystem.path()); + if (element) { + this._elementByPath.delete(fileSystem.path()); + element.remove(); + } }, __proto__: WebInspector.SettingsTab.prototype
diff --git a/third_party/WebKit/Source/devtools/front_end/settings/module.json b/third_party/WebKit/Source/devtools/front_end/settings/module.json index 3346d00..2f7cd7e 100644 --- a/third_party/WebKit/Source/devtools/front_end/settings/module.json +++ b/third_party/WebKit/Source/devtools/front_end/settings/module.json
@@ -51,7 +51,7 @@ "components" ], "scripts": [ - "EditFileSystemDialog.js", + "EditFileSystemView.js", "SettingsScreen.js", "FrameworkBlackboxSettingsTab.js" ]
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/NavigatorView.js b/third_party/WebKit/Source/devtools/front_end/sources/NavigatorView.js index cf00c39..38f03e3 100644 --- a/third_party/WebKit/Source/devtools/front_end/sources/NavigatorView.js +++ b/third_party/WebKit/Source/devtools/front_end/sources/NavigatorView.js
@@ -669,7 +669,7 @@ this.listItemElement.classList.add(this._iconClasses[i]); } - this.listItemElement.createChild("div", "selection"); + this.listItemElement.createChild("div", "selection fill"); if (!this._noIcon) this.imageElement = this.listItemElement.createChild("img", "icon");
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/navigatorView.css b/third_party/WebKit/Source/devtools/front_end/sources/navigatorView.css index 8eba492c8..85119fa 100644 --- a/third_party/WebKit/Source/devtools/front_end/sources/navigatorView.css +++ b/third_party/WebKit/Source/devtools/front_end/sources/navigatorView.css
@@ -69,10 +69,6 @@ color: white; } -.navigator li.selected .selection { - height: 18px; -} - .navigator > ol.being-edited li.selected .selection { background-color: rgb(56, 121, 217); }
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/helpScreen.css b/third_party/WebKit/Source/devtools/front_end/ui/helpScreen.css index 1078170..03be39c 100644 --- a/third_party/WebKit/Source/devtools/front_end/ui/helpScreen.css +++ b/third_party/WebKit/Source/devtools/front_end/ui/helpScreen.css
@@ -315,11 +315,6 @@ margin-right: 20px; } -.settings-tab .settings-list-container { - background-color: white; - margin-bottom: 10px; -} - .settings-tab .settings-list { border: 1px solid hsl(0, 0%, 85%); border-radius: 2px; @@ -443,16 +438,30 @@ margin-left: 0; } -.settings-tab .settings-list .settings-list-item .file-system-path { +.settings-tab .file-system-container { + margin-bottom: 20px; +} + +.settings-tab .file-system-header { + display: flex; + flex-direction: row; + align-items: baseline; +} + +.settings-tab .file-system-path { white-space: nowrap; - font-size: 12px; - padding-left: 6px; + font-size: 1.4em; padding-right: 5px; -webkit-box-flex: 1; color: hsl(210, 16%, 22%); + margin-bottom: 8px; + overflow: hidden; + flex: 0 1 auto; + margin-right: 5px; + text-overflow: ellipsis; } -.settings-tab .settings-list .settings-list-item .file-system-path-name { +.settings-tab .file-system-path-name { padding-right: 6px; font-weight: bold; } @@ -481,6 +490,10 @@ width: 20%; } +.excluded-folders-header { + margin-top: 10px; +} + .excluded-folders-list .settings-list-item .list-column.settings-list-column-path { width: 100%; } @@ -493,7 +506,6 @@ .settings-dialog { display: -webkit-flex; -webkit-flex-direction: column; - background: white; } .settings-dialog .dialog-contents {
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/treeoutline.css b/third_party/WebKit/Source/devtools/front_end/ui/treeoutline.css index 53b1e380..f7f6ce0 100644 --- a/third_party/WebKit/Source/devtools/front_end/ui/treeoutline.css +++ b/third_party/WebKit/Source/devtools/front_end/ui/treeoutline.css
@@ -21,12 +21,9 @@ .tree-outline li .selection { display: none; - position: absolute; - left: 0; - right: 0; - height: 17px; z-index: -1; margin-top: -1px; + margin-left: -10000px; } .tree-outline li.selected .selection { @@ -71,6 +68,7 @@ overflow: hidden; min-height: 17px; padding-top: 2px; + position: relative; } ol.tree-outline:focus li.selected {
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/treeoutline.js b/third_party/WebKit/Source/devtools/front_end/ui/treeoutline.js index e43d1437..c8f4645 100644 --- a/third_party/WebKit/Source/devtools/front_end/ui/treeoutline.js +++ b/third_party/WebKit/Source/devtools/front_end/ui/treeoutline.js
@@ -693,7 +693,7 @@ if (!this.treeOutline || !this.treeOutline._renderSelection) return; if (!this._selectionElement) - this._selectionElement = createElementWithClass("div", "selection"); + this._selectionElement = createElementWithClass("div", "selection fill"); this._listItemNode.insertBefore(this._selectionElement, this.listItemElement.firstChild); }, @@ -914,8 +914,6 @@ return false; this.treeOutline.selectedTreeElement = this; this._listItemNode.classList.add("selected"); - if (this._selectionElement) - this._selectionElement.style.height = this._listItemNode.offsetHeight + "px"; this.treeOutline.dispatchEventToListeners(TreeOutline.Events.ElementSelected, this); return this.onselect(selectedByUser); },
diff --git a/third_party/WebKit/Source/devtools/protocol.json b/third_party/WebKit/Source/devtools/protocol.json index adf6e9b..db8074c1 100644 --- a/third_party/WebKit/Source/devtools/protocol.json +++ b/third_party/WebKit/Source/devtools/protocol.json
@@ -5189,8 +5189,7 @@ { "name": "type", "$ref": "AXValueType", "description": "The type of this value." }, { "name": "value", "type": "any", "description": "The computed value of this property.", "optional": true }, - { "name": "relatedNodeValue", "$ref": "AXRelatedNode", "description": "The related node value, if any.", "optional": true }, - { "name": "relatedNodeArrayValue", "type": "array", "items": { "$ref": "AXRelatedNode" }, "description": "Multiple relted nodes, if applicable.", "optional": true }, + { "name": "relatedNodes", "type": "array", "items": { "$ref": "AXRelatedNode" }, "description": "One or more related nodes, if applicable.", "optional": true }, { "name": "sources", "type": "array", "items": { "$ref": "AXValueSource" }, "description": "The sources which contributed to the computation of this property.", "optional": true } ], "description": "A single computed AX property."
diff --git a/third_party/WebKit/Source/modules/accessibility/InspectorAccessibilityAgent.cpp b/third_party/WebKit/Source/modules/accessibility/InspectorAccessibilityAgent.cpp index 79a81d3..541b8df1 100644 --- a/third_party/WebKit/Source/modules/accessibility/InspectorAccessibilityAgent.cpp +++ b/third_party/WebKit/Source/modules/accessibility/InspectorAccessibilityAgent.cpp
@@ -69,7 +69,7 @@ properties->addItem(createProperty(AXLiveRegionAttributes::Busy, createBooleanValue(axObject->containerLiveRegionBusy()))); if (!axObject->isLiveRegion()) - properties->addItem(createProperty(AXLiveRegionAttributes::Root, createRelatedNodeValue(axObject->liveRegionRoot()))); + properties->addItem(createProperty(AXLiveRegionAttributes::Root, createRelatedNodeListValue(axObject->liveRegionRoot()))); } void fillGlobalStates(AXObject* axObject, PassRefPtr<TypeBuilder::Array<AXProperty>> properties) @@ -79,7 +79,7 @@ if (const AXObject* hiddenRoot = axObject->ariaHiddenRoot()) { properties->addItem(createProperty(AXGlobalStates::Hidden, createBooleanValue(true))); - properties->addItem(createProperty(AXGlobalStates::HiddenRoot, createRelatedNodeValue(hiddenRoot))); + properties->addItem(createProperty(AXGlobalStates::HiddenRoot, createRelatedNodeListValue(hiddenRoot))); } InvalidState invalidState = axObject->invalidState(); @@ -258,7 +258,7 @@ void fillRelationships(AXObject* axObject, PassRefPtr<TypeBuilder::Array<AXProperty>> properties) { if (AXObject* activeDescendant = axObject->activeDescendant()) { - properties->addItem(createProperty(AXRelationshipAttributes::Activedescendant, createRelatedNodeValue(activeDescendant))); + properties->addItem(createProperty(AXRelationshipAttributes::Activedescendant, createRelatedNodeListValue(activeDescendant))); } AXObject::AXObjectVector results;
diff --git a/third_party/WebKit/Source/modules/accessibility/InspectorTypeBuilderHelper.cpp b/third_party/WebKit/Source/modules/accessibility/InspectorTypeBuilderHelper.cpp index 0e7c8100..f5c8c59 100644 --- a/third_party/WebKit/Source/modules/accessibility/InspectorTypeBuilderHelper.cpp +++ b/third_party/WebKit/Source/modules/accessibility/InspectorTypeBuilderHelper.cpp
@@ -92,7 +92,7 @@ PassRefPtr<AXProperty> createProperty(IgnoredReason reason) { if (reason.relatedObject) - return createProperty(ignoredReasonName(reason.reason), createRelatedNodeValue(reason.relatedObject, nullptr, AXValueType::Idref)); + return createProperty(ignoredReasonName(reason.reason), createRelatedNodeListValue(reason.relatedObject, nullptr, AXValueType::Idref)); return createProperty(ignoredReasonName(reason.reason), createBooleanValue(true)); } @@ -146,11 +146,13 @@ return relatedNode; } -PassRefPtr<AXValue> createRelatedNodeValue(const AXObject* axObject, String* name, AXValueType::Enum valueType) +PassRefPtr<AXValue> createRelatedNodeListValue(const AXObject* axObject, String* name, AXValueType::Enum valueType) { RefPtr<AXValue> axValue = AXValue::create().setType(valueType); RefPtr<AXRelatedNode> relatedNode = relatedNodeForAXObject(axObject, name); - axValue->setRelatedNodeValue(relatedNode); + RefPtr<TypeBuilder::Array<AXRelatedNode>> relatedNodes = TypeBuilder::Array<AXRelatedNode>::create(); + relatedNodes->addItem(relatedNode); + axValue->setRelatedNodes(relatedNodes); return axValue; } @@ -163,7 +165,7 @@ frontendRelatedNodes->addItem(frontendRelatedNode); } RefPtr<AXValue> axValue = AXValue::create().setType(valueType); - axValue->setRelatedNodeArrayValue(frontendRelatedNodes); + axValue->setRelatedNodes(frontendRelatedNodes); return axValue; } @@ -176,7 +178,7 @@ relatedNodes->addItem(relatedNode); } RefPtr<AXValue> axValue = AXValue::create().setType(valueType); - axValue->setRelatedNodeArrayValue(relatedNodes); + axValue->setRelatedNodes(relatedNodes); return axValue; }
diff --git a/third_party/WebKit/Source/modules/accessibility/InspectorTypeBuilderHelper.h b/third_party/WebKit/Source/modules/accessibility/InspectorTypeBuilderHelper.h index e2876b3..143acb2 100644 --- a/third_party/WebKit/Source/modules/accessibility/InspectorTypeBuilderHelper.h +++ b/third_party/WebKit/Source/modules/accessibility/InspectorTypeBuilderHelper.h
@@ -34,7 +34,7 @@ PassRefPtr<AXValue> createValue(int value, AXValueType::Enum = AXValueType::Integer); PassRefPtr<AXValue> createValue(float value, AXValueType::Enum = AXValueType::Number); PassRefPtr<AXValue> createBooleanValue(bool value, AXValueType::Enum = AXValueType::Boolean); -PassRefPtr<AXValue> createRelatedNodeValue(const AXObject*, String* name = nullptr, AXValueType::Enum = AXValueType::Idref); +PassRefPtr<AXValue> createRelatedNodeListValue(const AXObject*, String* name = nullptr, AXValueType::Enum = AXValueType::Idref); PassRefPtr<AXValue> createRelatedNodeListValue(AXRelatedObjectVector&, AXValueType::Enum); PassRefPtr<AXValue> createRelatedNodeListValue(AXObject::AXObjectVector& axObjects, AXValueType::Enum = AXValueType::IdrefList);
diff --git a/third_party/WebKit/Source/modules/mediarecorder/MediaRecorder.cpp b/third_party/WebKit/Source/modules/mediarecorder/MediaRecorder.cpp index bd0f537..d24c1b83 100644 --- a/third_party/WebKit/Source/modules/mediarecorder/MediaRecorder.cpp +++ b/third_party/WebKit/Source/modules/mediarecorder/MediaRecorder.cpp
@@ -104,6 +104,7 @@ m_state = State::Recording; m_recorderHandler->start(timeSlice); + scheduleDispatchEvent(Event::create(EventTypeNames::start)); } void MediaRecorder::stop(ExceptionState& exceptionState) @@ -144,6 +145,7 @@ m_state = State::Recording; m_recorderHandler->resume(); + scheduleDispatchEvent(Event::create(EventTypeNames::resume)); } void MediaRecorder::requestData(ExceptionState& exceptionState)
diff --git a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in index 479e5d4..7a1ce07 100644 --- a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in +++ b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in
@@ -155,7 +155,6 @@ SlimmingPaintV2 SlimmingPaintOffsetCaching implied_by=SlimmingPaintV2, implied_by=SlimmingPaintSynchronizedPainting SlimmingPaintStrictCullRectClipping -SlimmingPaintSubsequenceCaching implied_by=SlimmingPaintV2 SlimmingPaintSynchronizedPainting implied_by=SlimmingPaintV2 SlimmingPaintUnderInvalidationChecking StackedCSSPropertyAnimations status=experimental
diff --git a/third_party/WebKit/Source/platform/graphics/ContentLayerDelegate.cpp b/third_party/WebKit/Source/platform/graphics/ContentLayerDelegate.cpp index 86569bc..fc5f41d 100644 --- a/third_party/WebKit/Source/platform/graphics/ContentLayerDelegate.cpp +++ b/third_party/WebKit/Source/platform/graphics/ContentLayerDelegate.cpp
@@ -66,16 +66,6 @@ } void ContentLayerDelegate::paintContents( - SkCanvas* canvas, const WebRect& clip, - WebContentLayerClient::PaintingControlSetting paintingControl) -{ - TRACE_EVENT1("blink,benchmark", "ContentLayerDelegate::paintContents", "clip_rect", toTracedValue(clip)); - - // TODO(pdr): Remove this function. - ASSERT_NOT_REACHED(); -} - -void ContentLayerDelegate::paintContents( WebDisplayItemList* webDisplayItemList, const WebRect& clip, WebContentLayerClient::PaintingControlSetting paintingControl) { @@ -103,7 +93,7 @@ if (paintingControl == WebContentLayerClient::DisplayListPaintingDisabled || paintingControl == WebContentLayerClient::DisplayListConstructionDisabled) disabledMode = GraphicsContext::FullyDisabled; - GraphicsContext context(paintController, disabledMode); + GraphicsContext context(*paintController, disabledMode); m_painter->paint(context, clip);
diff --git a/third_party/WebKit/Source/platform/graphics/ContentLayerDelegate.h b/third_party/WebKit/Source/platform/graphics/ContentLayerDelegate.h index 9d055181..387c42cb 100644 --- a/third_party/WebKit/Source/platform/graphics/ContentLayerDelegate.h +++ b/third_party/WebKit/Source/platform/graphics/ContentLayerDelegate.h
@@ -58,7 +58,6 @@ ~ContentLayerDelegate() override; // WebContentLayerClient implementation. - void paintContents(SkCanvas*, const WebRect& clip, WebContentLayerClient::PaintingControlSetting = PaintDefaultBehavior) override; void paintContents(WebDisplayItemList*, const WebRect& clip, WebContentLayerClient::PaintingControlSetting = PaintDefaultBehavior) override; size_t approximateUnsharedMemoryUsage() const override;
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsContext.cpp b/third_party/WebKit/Source/platform/graphics/GraphicsContext.cpp index 8a211e6..ae42a0b 100644 --- a/third_party/WebKit/Source/platform/graphics/GraphicsContext.cpp +++ b/third_party/WebKit/Source/platform/graphics/GraphicsContext.cpp
@@ -50,7 +50,7 @@ namespace blink { -GraphicsContext::GraphicsContext(PaintController* paintController, DisabledMode disableContextOrPainting, SkMetaData* metaData) +GraphicsContext::GraphicsContext(PaintController& paintController, DisabledMode disableContextOrPainting, SkMetaData* metaData) : m_canvas(nullptr) , m_originalCanvas(nullptr) , m_paintController(paintController) @@ -66,9 +66,6 @@ , m_printing(false) , m_hasMetaData(!!metaData) { - // TODO(chrishtr): switch the type of the parameter to PaintController&. - ASSERT(paintController); - if (metaData) m_metaData = *metaData; @@ -734,7 +731,7 @@ return; if (font.drawText(m_canvas, runInfo, point, m_deviceScaleFactor, paint)) - m_paintController->setTextPainted(); + m_paintController.setTextPainted(); } template<typename DrawTextFunc> @@ -762,7 +759,7 @@ drawTextPasses([&font, &runInfo, &point, this](const SkPaint& paint) { if (font.drawText(m_canvas, runInfo, point, m_deviceScaleFactor, paint)) - m_paintController->setTextPainted(); + m_paintController.setTextPainted(); }); } @@ -783,7 +780,7 @@ drawTextPasses([&font, &runInfo, &point, customFontNotReadyAction, this](const SkPaint& paint) { if (font.drawBidiText(m_canvas, runInfo, point, customFontNotReadyAction, m_deviceScaleFactor, paint)) - m_paintController->setTextPainted(); + m_paintController.setTextPainted(); }); }
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsContext.h b/third_party/WebKit/Source/platform/graphics/GraphicsContext.h index 8491ed4..45980cc4 100644 --- a/third_party/WebKit/Source/platform/graphics/GraphicsContext.h +++ b/third_party/WebKit/Source/platform/graphics/GraphicsContext.h
@@ -69,14 +69,15 @@ FullyDisabled = 1 // Do absolutely minimal work to remove the cost of the context from performance tests. }; - explicit GraphicsContext(PaintController*, DisabledMode = NothingDisabled, SkMetaData* = 0); + explicit GraphicsContext(PaintController&, DisabledMode = NothingDisabled, SkMetaData* = 0); ~GraphicsContext(); SkCanvas* canvas() { return m_canvas; } const SkCanvas* canvas() const { return m_canvas; } - PaintController* paintController() { return m_paintController; } + // TODO(pdr): Update this to return a reference. + PaintController* paintController() { return &m_paintController; } bool contextDisabled() const { return m_disabledState; } @@ -343,8 +344,7 @@ // used when Slimming Paint is active. SkCanvas* m_originalCanvas; - // This being null indicates not to paint using the PaintController, and instead directly into the canvas. - PaintController* m_paintController; + PaintController& m_paintController; // Paint states stack. Enables local drawing state change with save()/restore() calls. // This state controls the appearance of drawn content.
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsContextTest.cpp b/third_party/WebKit/Source/platform/graphics/GraphicsContextTest.cpp index 91d4805d..56f0517 100644 --- a/third_party/WebKit/Source/platform/graphics/GraphicsContextTest.cpp +++ b/third_party/WebKit/Source/platform/graphics/GraphicsContextTest.cpp
@@ -70,7 +70,7 @@ SkCanvas canvas(bitmap); OwnPtr<PaintController> paintController = PaintController::create(); - GraphicsContext context(paintController.get()); + GraphicsContext context(*paintController); Color opaque(1.0f, 0.0f, 0.0f, 1.0f); FloatRect bounds(0, 0, 100, 100); @@ -103,7 +103,7 @@ FloatRect bounds(0, 0, 100, 100); OwnPtr<PaintController> paintController = PaintController::create(); - GraphicsContext context(paintController.get()); + GraphicsContext context(*paintController); context.beginRecording(bounds); context.setShouldAntialias(false);
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintControllerTest.cpp b/third_party/WebKit/Source/platform/graphics/paint/PaintControllerTest.cpp index 3d5ab62..459aba9 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/PaintControllerTest.cpp +++ b/third_party/WebKit/Source/platform/graphics/paint/PaintControllerTest.cpp
@@ -21,7 +21,7 @@ public: PaintControllerTest() : m_paintController(PaintController::create()) - , m_originalSlimmingPaintSubsequenceCachingEnabled(RuntimeEnabledFeatures::slimmingPaintSubsequenceCachingEnabled()) + , m_originalSlimmingPaintSynchronizedPaintingEnabled(RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEnabled()) , m_originalSlimmingPaintV2Enabled(RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { } protected: @@ -30,12 +30,12 @@ private: void TearDown() override { - RuntimeEnabledFeatures::setSlimmingPaintSubsequenceCachingEnabled(m_originalSlimmingPaintSubsequenceCachingEnabled); + RuntimeEnabledFeatures::setSlimmingPaintSynchronizedPaintingEnabled(m_originalSlimmingPaintSynchronizedPaintingEnabled); RuntimeEnabledFeatures::setSlimmingPaintV2Enabled(m_originalSlimmingPaintV2Enabled); } OwnPtr<PaintController> m_paintController; - bool m_originalSlimmingPaintSubsequenceCachingEnabled; + bool m_originalSlimmingPaintSynchronizedPaintingEnabled; bool m_originalSlimmingPaintV2Enabled; }; @@ -105,7 +105,7 @@ TEST_F(PaintControllerTest, NestedRecorders) { - GraphicsContext context(&paintController()); + GraphicsContext context(paintController()); TestDisplayItemClient client("client"); @@ -122,7 +122,7 @@ { TestDisplayItemClient first("first"); TestDisplayItemClient second("second"); - GraphicsContext context(&paintController()); + GraphicsContext context(paintController()); drawRect(context, first, backgroundDrawingType, FloatRect(100, 100, 300, 300)); drawRect(context, second, backgroundDrawingType, FloatRect(100, 100, 200, 200)); @@ -149,7 +149,7 @@ TestDisplayItemClient first("first"); TestDisplayItemClient second("second"); TestDisplayItemClient unaffected("unaffected"); - GraphicsContext context(&paintController()); + GraphicsContext context(paintController()); drawRect(context, first, backgroundDrawingType, FloatRect(100, 100, 100, 100)); drawRect(context, second, backgroundDrawingType, FloatRect(100, 100, 50, 200)); @@ -178,7 +178,7 @@ TestDisplayItemClient first("first"); TestDisplayItemClient second("second"); TestDisplayItemClient third("third"); - GraphicsContext context(&paintController()); + GraphicsContext context(paintController()); drawRect(context, first, backgroundDrawingType, FloatRect(100, 100, 100, 100)); drawRect(context, second, backgroundDrawingType, FloatRect(100, 100, 50, 200)); @@ -204,7 +204,7 @@ TestDisplayItemClient first("first"); TestDisplayItemClient second("second"); TestDisplayItemClient third("third"); - GraphicsContext context(&paintController()); + GraphicsContext context(paintController()); drawRect(context, first, backgroundDrawingType, FloatRect(100, 100, 100, 100)); drawRect(context, second, backgroundDrawingType, FloatRect(100, 100, 50, 200)); @@ -244,7 +244,7 @@ { TestDisplayItemClient first("first"); TestDisplayItemClient second("second"); - GraphicsContext context(&paintController()); + GraphicsContext context(paintController()); drawRect(context, second, backgroundDrawingType, FloatRect(200, 200, 50, 50)); drawRect(context, second, foregroundDrawingType, FloatRect(200, 200, 50, 50)); @@ -282,7 +282,7 @@ { TestDisplayItemClient first("first"); TestDisplayItemClient second("second"); - GraphicsContext context(&paintController()); + GraphicsContext context(paintController()); drawRect(context, first, backgroundDrawingType, FloatRect(100, 100, 150, 150)); drawRect(context, first, foregroundDrawingType, FloatRect(100, 100, 150, 150)); @@ -321,7 +321,7 @@ { TestDisplayItemClient first("first"); TestDisplayItemClient second("second"); - GraphicsContext context(&paintController()); + GraphicsContext context(paintController()); { ClipRecorder clipRecorder(context, first, clipType, LayoutRect(1, 1, 2, 2)); @@ -364,7 +364,7 @@ { TestDisplayItemClient first("first"); TestDisplayItemClient second("second"); - GraphicsContext context(&paintController()); + GraphicsContext context(paintController()); drawRect(context, first, backgroundDrawingType, FloatRect(100, 100, 150, 150)); drawRect(context, second, backgroundDrawingType, FloatRect(100, 100, 150, 150)); @@ -407,7 +407,7 @@ TestDisplayItemClient content1("content1"); TestDisplayItemClient container2("container2"); TestDisplayItemClient content2("content2"); - GraphicsContext context(&paintController()); + GraphicsContext context(paintController()); drawRect(context, container1, backgroundDrawingType, FloatRect(100, 100, 100, 100)); drawRect(context, content1, backgroundDrawingType, FloatRect(100, 100, 50, 200)); @@ -454,13 +454,13 @@ TEST_F(PaintControllerTest, CachedSubsequenceSwapOrder) { - RuntimeEnabledFeatures::setSlimmingPaintSubsequenceCachingEnabled(true); + RuntimeEnabledFeatures::setSlimmingPaintSynchronizedPaintingEnabled(true); TestDisplayItemClient container1("container1"); TestDisplayItemClient content1("content1"); TestDisplayItemClient container2("container2"); TestDisplayItemClient content2("content2"); - GraphicsContext context(&paintController()); + GraphicsContext context(paintController()); { SubsequenceRecorder r(context, container1, subsequenceType); @@ -522,7 +522,7 @@ TEST_F(PaintControllerTest, OutOfOrderNoCrash) { TestDisplayItemClient client("client"); - GraphicsContext context(&paintController()); + GraphicsContext context(paintController()); const DisplayItem::Type type1 = DisplayItem::DrawingFirst; const DisplayItem::Type type2 = static_cast<DisplayItem::Type>(DisplayItem::DrawingFirst + 1); @@ -546,13 +546,13 @@ TEST_F(PaintControllerTest, CachedNestedSubsequenceUpdate) { - RuntimeEnabledFeatures::setSlimmingPaintSubsequenceCachingEnabled(true); + RuntimeEnabledFeatures::setSlimmingPaintSynchronizedPaintingEnabled(true); TestDisplayItemClient container1("container1"); TestDisplayItemClient content1("content1"); TestDisplayItemClient container2("container2"); TestDisplayItemClient content2("content2"); - GraphicsContext context(&paintController()); + GraphicsContext context(paintController()); { SubsequenceRecorder r(context, container1, subsequenceType); @@ -643,7 +643,7 @@ { TestDisplayItemClient multicol("multicol"); TestDisplayItemClient content("content"); - GraphicsContext context(&paintController()); + GraphicsContext context(paintController()); FloatRect rect1(100, 100, 50, 50); FloatRect rect2(150, 100, 50, 50); @@ -727,7 +727,7 @@ TestDisplayItemClient second("second"); TestDisplayItemClient third("third"); - GraphicsContext context(&paintController()); + GraphicsContext context(paintController()); drawRect(context, first, backgroundDrawingType, FloatRect(0, 0, 100, 100)); { ClipPathRecorder clipRecorder(context, second, Path()); @@ -780,7 +780,7 @@ RuntimeEnabledFeatures::setSlimmingPaintV2Enabled(true); TestDisplayItemClient client("test client"); - GraphicsContext context(&paintController()); + GraphicsContext context(paintController()); drawRect(context, client, backgroundDrawingType, FloatRect(0, 0, 100, 100)); paintController().commitNewDisplayItems();
diff --git a/third_party/WebKit/Source/platform/graphics/paint/SkPictureBuilder.h b/third_party/WebKit/Source/platform/graphics/paint/SkPictureBuilder.h index 900a420..a9341ac 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/SkPictureBuilder.h +++ b/third_party/WebKit/Source/platform/graphics/paint/SkPictureBuilder.h
@@ -26,7 +26,7 @@ disabledMode = GraphicsContext::FullyDisabled; m_paintController = PaintController::create(); - m_context = adoptPtr(new GraphicsContext(m_paintController.get(), disabledMode, metaData)); + m_context = adoptPtr(new GraphicsContext(*m_paintController, disabledMode, metaData)); if (containingContext) { m_context->setDeviceScaleFactor(containingContext->deviceScaleFactor());
diff --git a/third_party/WebKit/Source/platform/graphics/paint/SubsequenceRecorder.cpp b/third_party/WebKit/Source/platform/graphics/paint/SubsequenceRecorder.cpp index 6a18932..4942152 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/SubsequenceRecorder.cpp +++ b/third_party/WebKit/Source/platform/graphics/paint/SubsequenceRecorder.cpp
@@ -15,7 +15,7 @@ bool SubsequenceRecorder::useCachedSubsequenceIfPossible(GraphicsContext& context, const DisplayItemClientWrapper& client, DisplayItem::Type type) { - if (!RuntimeEnabledFeatures::slimmingPaintSubsequenceCachingEnabled()) + if (!RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEnabled()) return false; ASSERT(context.paintController()); @@ -44,7 +44,7 @@ , m_beginSubsequenceIndex(0) , m_type(type) { - if (!RuntimeEnabledFeatures::slimmingPaintSubsequenceCachingEnabled()) + if (!RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEnabled()) return; ASSERT(m_paintController); @@ -57,7 +57,7 @@ SubsequenceRecorder::~SubsequenceRecorder() { - if (!RuntimeEnabledFeatures::slimmingPaintSubsequenceCachingEnabled()) + if (!RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEnabled()) return; if (m_paintController->displayItemConstructionIsDisabled()) @@ -78,7 +78,7 @@ void SubsequenceRecorder::setUncacheable() { - if (!RuntimeEnabledFeatures::slimmingPaintSubsequenceCachingEnabled()) + if (!RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEnabled()) return; if (m_paintController->displayItemConstructionIsDisabled())
diff --git a/third_party/WebKit/Source/web/ChromeClientImpl.cpp b/third_party/WebKit/Source/web/ChromeClientImpl.cpp index 5577228..b53773a 100644 --- a/third_party/WebKit/Source/web/ChromeClientImpl.cpp +++ b/third_party/WebKit/Source/web/ChromeClientImpl.cpp
@@ -662,13 +662,13 @@ return m_lastSetMouseCursorForTesting; } -void ChromeClientImpl::setCursor(const Cursor& cursor) +void ChromeClientImpl::setCursor(const Cursor& cursor, LocalFrame* localRoot) { m_lastSetMouseCursorForTesting = cursor; - setCursor(WebCursorInfo(cursor)); + setCursor(WebCursorInfo(cursor), localRoot); } -void ChromeClientImpl::setCursor(const WebCursorInfo& cursor) +void ChromeClientImpl::setCursor(const WebCursorInfo& cursor, LocalFrame* localRoot) { if (m_cursorOverridden) return; @@ -679,13 +679,25 @@ if (m_webView->hasOpenedPopup()) return; #endif - if (m_webView->client()) + if (!m_webView->client()) + return; + // TODO(kenrb, dcheng): For top-level frames we still use the WebView as + // a WebWidget. This special case will be removed when top-level frames + // get WebFrameWidgets. + if (localRoot->isMainFrame()) { m_webView->client()->didChangeCursor(cursor); + } else { + WebLocalFrameImpl* webFrame = WebLocalFrameImpl::fromFrame(localRoot); + ASSERT(webFrame); + ASSERT(webFrame->frameWidget()); + if (toWebFrameWidgetImpl(webFrame->frameWidget())->client()) + toWebFrameWidgetImpl(webFrame->frameWidget())->client()->didChangeCursor(cursor); + } } void ChromeClientImpl::setCursorForPlugin(const WebCursorInfo& cursor) { - setCursor(cursor); + setCursor(cursor, m_webView->page()->deprecatedLocalMainFrame()); } void ChromeClientImpl::setCursorOverridden(bool overridden)
diff --git a/third_party/WebKit/Source/web/ChromeClientImpl.h b/third_party/WebKit/Source/web/ChromeClientImpl.h index 46054cdd..bed75e3 100644 --- a/third_party/WebKit/Source/web/ChromeClientImpl.h +++ b/third_party/WebKit/Source/web/ChromeClientImpl.h
@@ -110,7 +110,7 @@ PassRefPtr<DateTimeChooser> openDateTimeChooser(DateTimeChooserClient*, const DateTimeChooserParameters&) override; void openFileChooser(LocalFrame*, PassRefPtr<FileChooser>) override; void enumerateChosenDirectory(FileChooser*) override; - void setCursor(const Cursor&) override; + void setCursor(const Cursor&, LocalFrame* localRoot) override; Cursor lastSetCursorForTesting() const override; void needTouchEvents(bool needTouchEvents) override; void setTouchAction(TouchAction) override; @@ -184,7 +184,7 @@ void unregisterPopupOpeningObserver(PopupOpeningObserver*) override; void notifyPopupOpeningObservers() const; - void setCursor(const WebCursorInfo&); + void setCursor(const WebCursorInfo&, LocalFrame* localRoot); WebViewImpl* m_webView; // Weak pointer. WindowFeatures m_windowFeatures;
diff --git a/third_party/WebKit/Source/web/InspectorOverlay.cpp b/third_party/WebKit/Source/web/InspectorOverlay.cpp index 3709007..b39e27b 100644 --- a/third_party/WebKit/Source/web/InspectorOverlay.cpp +++ b/third_party/WebKit/Source/web/InspectorOverlay.cpp
@@ -138,10 +138,10 @@ EmptyChromeClient::trace(visitor); } - void setCursor(const Cursor& cursor) override + void setCursor(const Cursor& cursor, LocalFrame* localRoot) override { toChromeClientImpl(m_client)->setCursorOverridden(false); - toChromeClientImpl(m_client)->setCursor(cursor); + toChromeClientImpl(m_client)->setCursor(cursor, localRoot); bool overrideCursor = m_overlay->m_layoutEditor; toChromeClientImpl(m_client)->setCursorOverridden(overrideCursor); } @@ -633,7 +633,7 @@ highlightNode(m_hoveredNodeForInspectMode.get(), *m_inspectModeHighlightConfig, false); toChromeClientImpl(m_webViewImpl->page()->chromeClient()).setCursorOverridden(false); - toChromeClientImpl(m_webViewImpl->page()->chromeClient()).setCursor(pointerCursor()); + toChromeClientImpl(m_webViewImpl->page()->chromeClient()).setCursor(pointerCursor(), overlayMainFrame()); } void InspectorOverlay::profilingStarted()
diff --git a/third_party/WebKit/Source/web/LinkHighlightImpl.cpp b/third_party/WebKit/Source/web/LinkHighlightImpl.cpp index b7cb039..98232f4 100644 --- a/third_party/WebKit/Source/web/LinkHighlightImpl.cpp +++ b/third_party/WebKit/Source/web/LinkHighlightImpl.cpp
@@ -257,18 +257,6 @@ return pathHasChanged; } -void LinkHighlightImpl::paintContents(WebCanvas* canvas, const WebRect&, WebContentLayerClient::PaintingControlSetting paintingControl) -{ - if (!m_node || !m_node->layoutObject()) - return; - - SkPaint paint; - paint.setStyle(SkPaint::kFill_Style); - paint.setFlags(SkPaint::kAntiAlias_Flag); - paint.setColor(m_node->layoutObject()->style()->tapHighlightColor().rgb()); - canvas->drawPath(m_path.skPath(), paint); -} - void LinkHighlightImpl::paintContents(WebDisplayItemList* webDisplayItemList, const WebRect& webClipRect, WebContentLayerClient::PaintingControlSetting paintingControl) { if (!m_node || !m_node->layoutObject()) @@ -277,7 +265,13 @@ SkPictureRecorder recorder; SkCanvas* canvas = recorder.beginRecording(webClipRect.width, webClipRect.height); canvas->translate(-webClipRect.x, -webClipRect.y); - paintContents(canvas, webClipRect, paintingControl); + + SkPaint paint; + paint.setStyle(SkPaint::kFill_Style); + paint.setFlags(SkPaint::kAntiAlias_Flag); + paint.setColor(m_node->layoutObject()->style()->tapHighlightColor().rgb()); + canvas->drawPath(m_path.skPath(), paint); + RefPtr<const SkPicture> picture = adoptRef(recorder.endRecording()); webDisplayItemList->appendDrawingItem(picture.get()); }
diff --git a/third_party/WebKit/Source/web/LinkHighlightImpl.h b/third_party/WebKit/Source/web/LinkHighlightImpl.h index fe34dae..64235b7 100644 --- a/third_party/WebKit/Source/web/LinkHighlightImpl.h +++ b/third_party/WebKit/Source/web/LinkHighlightImpl.h
@@ -60,7 +60,6 @@ void updateGeometry(); // WebContentLayerClient implementation. - void paintContents(WebCanvas*, const WebRect& clipRect, WebContentLayerClient::PaintingControlSetting) override; void paintContents(WebDisplayItemList*, const WebRect& clipRect, WebContentLayerClient::PaintingControlSetting) override; // WebCompositorAnimationDelegate implementation.
diff --git a/third_party/WebKit/Source/web/PageOverlayTest.cpp b/third_party/WebKit/Source/web/PageOverlayTest.cpp index a64de62c..0a19a8d0 100644 --- a/third_party/WebKit/Source/web/PageOverlayTest.cpp +++ b/third_party/WebKit/Source/web/PageOverlayTest.cpp
@@ -152,12 +152,14 @@ // Paint the layer with a null canvas to get a display list, and then // replay that onto the mock canvas for examination. - GraphicsContext graphicsContext(graphicsLayer->paintController()); + PaintController* paintController = graphicsLayer->paintController(); + ASSERT(paintController); + GraphicsContext graphicsContext(*paintController); graphicsLayer->paint(graphicsContext, rect); graphicsContext.beginRecording(IntRect(rect)); - graphicsLayer->paintController()->commitNewDisplayItems(); - graphicsLayer->paintController()->paintArtifact().replay(graphicsContext); + paintController->commitNewDisplayItems(); + paintController->paintArtifact().replay(graphicsContext); graphicsContext.endRecording()->playback(&canvas); }
diff --git a/third_party/WebKit/Source/web/WebDevToolsAgentImpl.cpp b/third_party/WebKit/Source/web/WebDevToolsAgentImpl.cpp index 1f2c807..7234d0b 100644 --- a/third_party/WebKit/Source/web/WebDevToolsAgentImpl.cpp +++ b/third_party/WebKit/Source/web/WebDevToolsAgentImpl.cpp
@@ -469,7 +469,7 @@ m_agents.append(InspectorInputAgent::create(m_inspectedFrames.get())); v8::Isolate* isolate = V8PerIsolateData::mainThreadIsolate(); - m_agents.append(InspectorProfilerAgent::create(isolate, injectedScriptManager, m_overlay.get())); + m_agents.append(InspectorProfilerAgent::create(isolate, m_overlay.get())); m_agents.append(InspectorHeapProfilerAgent::create(isolate, injectedScriptManager));
diff --git a/third_party/WebKit/Source/web/WebPagePopupImpl.cpp b/third_party/WebKit/Source/web/WebPagePopupImpl.cpp index 6f14730..208acec 100644 --- a/third_party/WebKit/Source/web/WebPagePopupImpl.cpp +++ b/third_party/WebKit/Source/web/WebPagePopupImpl.cpp
@@ -157,7 +157,7 @@ return IntSize(0, 0); } - void setCursor(const Cursor& cursor) override + void setCursor(const Cursor& cursor, LocalFrame* localRoot) override { if (m_popup->m_webView->client()) m_popup->m_webView->client()->didChangeCursor(WebCursorInfo(cursor));
diff --git a/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp b/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp index 5715802c..bd2e7d0e 100644 --- a/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp +++ b/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp
@@ -724,8 +724,10 @@ for (size_t i = 0; i < m_pluginLoadObservers.size(); ++i) m_pluginLoadObservers[i]->clearPluginContainer(); - if (m_webPlugin) + if (m_webPlugin) { + RELEASE_ASSERT(!m_webPlugin->container() || m_webPlugin->container() == this); m_webPlugin->destroy(); + } m_webPlugin = nullptr; if (m_webLayer) {
diff --git a/third_party/WebKit/Tools/Scripts/run-blink-wptserve b/third_party/WebKit/Tools/Scripts/run-blink-wptserve new file mode 100755 index 0000000..f94e7c85 --- /dev/null +++ b/third_party/WebKit/Tools/Scripts/run-blink-wptserve
@@ -0,0 +1,15 @@ +#!/usr/bin/env python +# 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. + +# Runs an instance of wptserve to allow manual testing of the imported Web +# Platform Tests. The main HTTP server is run on 8001, while the main HTTPS +# server is run on 8444. + +import webkitpy.common.version_check + +from webkitpy.layout_tests.servers import cli_wrapper +from webkitpy.layout_tests.servers import wptserve + +cli_wrapper.main(wptserve.WPTServe)
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py index 1f962942..619585f 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py
@@ -474,6 +474,8 @@ self._port.clobber_old_port_specific_results() def _tests_to_retry(self, run_results): + # TODO(ojan): This should also check that result.type != test_expectations.MISSING since retrying missing expectations is silly. + # But that's a bit tricky since we only consider the last retry attempt for the count of unexpected regressions. return [result.test_name for result in run_results.unexpected_results_by_name.values() if result.type != test_expectations.PASS] def _write_json_files(self, summarized_full_results, summarized_failing_results, initial_results, running_all_tests):
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py index 086891b..4c2f2bc 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py
@@ -128,9 +128,15 @@ default=False, help="Save generated results as new baselines " "into the *most-specific-platform* directory, overwriting whatever's " "already there. Equivalent to --reset-results --add-platform-exceptions"), - optparse.make_option("--no-new-test-results", action="store_false", - dest="new_test_results", default=True, - help="Don't create new baselines when no expected results exist"), + + # TODO(ojan): Remove once bots stop using it. + optparse.make_option("--no-new-test-results", + help="This doesn't do anything. TODO(ojan): Remove once bots stop using it."), + + optparse.make_option("--new-test-results", action="store_true", + default=False, + help="Create new baselines when no expected results exist"), + optparse.make_option("--no-show-results", action="store_false", default=True, dest="show_results", help="Don't launch a browser with results after the tests "
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py index 7b1bc85..9814900 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py
@@ -62,8 +62,8 @@ args = [] if not '--platform' in extra_args: args.extend(['--platform', 'test']) - if not new_results: - args.append('--no-new-test-results') + if new_results: + args.append('--new-test-results') if not '--child-processes' in extra_args: args.extend(['--child-processes', 1])
diff --git a/third_party/WebKit/public/platform/WebContentLayerClient.h b/third_party/WebKit/public/platform/WebContentLayerClient.h index abf25d7..7e28aee 100644 --- a/third_party/WebKit/public/platform/WebContentLayerClient.h +++ b/third_party/WebKit/public/platform/WebContentLayerClient.h
@@ -26,7 +26,6 @@ #ifndef WebContentLayerClient_h #define WebContentLayerClient_h -#include "WebCanvas.h" #include "WebCommon.h" namespace blink { @@ -44,13 +43,6 @@ }; // Paints the content area for the layer, typically dirty rects submitted - // through WebContentLayer::setNeedsDisplay, submitting drawing commands - // through the WebCanvas. - // The canvas is already clipped to the |clip| rect. - // The |PaintingControlSetting| enum controls painting to isolate different components in performance tests. - virtual void paintContents(WebCanvas*, const WebRect& clip, PaintingControlSetting = PaintDefaultBehavior) = 0; - - // Paints the content area for the layer, typically dirty rects submitted // through WebContentLayer::setNeedsDisplayInRect, submitting drawing commands // to populate the WebDisplayItemList. // The |clip| rect defines the region of interest. The resulting WebDisplayItemList should contain
diff --git a/third_party/WebKit/public/web/WebInputEvent.h b/third_party/WebKit/public/web/WebInputEvent.h index 4751e088..53ca6a160 100644 --- a/third_party/WebKit/public/web/WebInputEvent.h +++ b/third_party/WebKit/public/web/WebInputEvent.h
@@ -283,6 +283,11 @@ // easier to leave it always false than ifdef. bool isSystemKey; + // Whether the event forms part of a browser-handled keyboard shortcut. + // This can be used to conditionally suppress Char events after a + // shortcut-triggering RawKeyDown goes unhandled. + bool isBrowserShortcut; + // |text| is the text generated by this keystroke. |unmodifiedText| is // |text|, but unmodified by an concurrently-held modifiers (except // shift). This is useful for working out shortcut keys. Linux and @@ -300,6 +305,7 @@ , windowsKeyCode(0) , nativeKeyCode(0) , isSystemKey(false) + , isBrowserShortcut(false) { memset(&text, 0, sizeof(text)); memset(&unmodifiedText, 0, sizeof(unmodifiedText));
diff --git a/third_party/WebKit/public/web/WebPlugin.h b/third_party/WebKit/public/web/WebPlugin.h index 20aaf78..58888f6c1 100644 --- a/third_party/WebKit/public/web/WebPlugin.h +++ b/third_party/WebKit/public/web/WebPlugin.h
@@ -61,14 +61,21 @@ class WebPlugin { public: + // Perform any initialization work given the container this plugin will use to + // communicate with renderer code. Plugins that return false here must + // subsequently return nullptr for the container() method. virtual bool initialize(WebPluginContainer*) = 0; + + // Plugins must arrange for themselves to be deleted sometime during or after this + // method is called. virtual void destroy() = 0; - virtual WebPluginContainer* container() const { return 0; } + // Must return null container when the initialize() method returns false. + virtual WebPluginContainer* container() const { return nullptr; } virtual void containerDidDetachFromParent() { } - virtual NPObject* scriptableObject() { return 0; } - virtual struct _NPP* pluginNPP() { return 0; } + virtual NPObject* scriptableObject() { return nullptr; } + virtual struct _NPP* pluginNPP() { return nullptr; } // The same as scriptableObject() but allows to expose scriptable interface // through plain v8 object instead of NPObject.
diff --git a/third_party/binutils/download.py b/third_party/binutils/download.py index 6a760df..17c7868 100755 --- a/third_party/binutils/download.py +++ b/third_party/binutils/download.py
@@ -9,6 +9,7 @@ TODO(mithro): Replace with generic download_and_extract tool. """ +import argparse import os import platform import re @@ -98,10 +99,20 @@ def main(args): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('--ignore-if-arch', metavar='ARCH', + action='append', default=[], + help='Do nothing on host architecture ARCH') + + options = parser.parse_args(args) + if not sys.platform.startswith('linux'): return 0 arch = GetArch() + if arch in options.ignore_if_arch: + return 0 + if arch == 'x64': return FetchAndExtract(arch) if arch == 'ia32': @@ -110,9 +121,10 @@ return ret # Fetch the x64 toolchain as well for official bots with 64-bit kernels. return FetchAndExtract('x64') + print "Host architecture %s is not supported." % arch return 1 if __name__ == '__main__': - sys.exit(main(sys.argv)) + sys.exit(main(sys.argv[1:]))
diff --git a/third_party/boringssl/boringssl.gypi b/third_party/boringssl/boringssl.gypi index 2f98c90c..1c6d010 100644 --- a/third_party/boringssl/boringssl.gypi +++ b/third_party/boringssl/boringssl.gypi
@@ -34,7 +34,6 @@ 'src/ssl/ssl_rsa.c', 'src/ssl/ssl_session.c', 'src/ssl/ssl_stat.c', - 'src/ssl/ssl_txt.c', 'src/ssl/t1_enc.c', 'src/ssl/t1_lib.c', 'src/ssl/tls_record.c', @@ -152,6 +151,7 @@ 'src/crypto/ec/ec_key.c', 'src/crypto/ec/ec_montgomery.c', 'src/crypto/ec/oct.c', + 'src/crypto/ec/p224-64.c', 'src/crypto/ec/p256-64.c', 'src/crypto/ec/simple.c', 'src/crypto/ec/util-64.c',
diff --git a/third_party/closure_compiler/compiler_test.py b/third_party/closure_compiler/compiler_test.py index 361d88c5..36cf163 100755 --- a/third_party/closure_compiler/compiler_test.py +++ b/third_party/closure_compiler/compiler_test.py
@@ -56,8 +56,9 @@ closure_args=args) return found_errors, stderr, out_file, out_map - def _runCheckerTestExpectError(self, source_code, expected_error): - _, stderr, out_file, out_map = self._runChecker(source_code) + def _runCheckerTestExpectError(self, source_code, expected_error, + closure_args=None): + _, stderr, out_file, out_map = self._runChecker(source_code, closure_args) self.assertTrue(expected_error in stderr, msg="Expected chunk: \n%s\n\nOutput:\n%s\n" % ( @@ -342,6 +343,31 @@ "cr.exportPath();", "ERROR - cr.exportPath() should have at least 1 argument: path name") + def testMissingReturnAssertNotReached(self): + template = self._ASSERT_DEFINITION + """ +/** @enum {number} */ +var Enum = {FOO: 1, BAR: 2}; + +/** + * @param {Enum} e + * @return {number} + */ +function enumToVal(e) { + switch (e) { + case Enum.FOO: + return 1; + case Enum.BAR: + return 2; + } + %s +} +""" + args = ['warning_level=VERBOSE'] + self._runCheckerTestExpectError(template % '', 'Missing return', + closure_args=args) + self._runCheckerTestExpectSuccess(template % 'assertNotReached();', + closure_args=args) + if __name__ == "__main__": unittest.main()
diff --git a/third_party/closure_compiler/externs/developer_private.js b/third_party/closure_compiler/externs/developer_private.js index 8fe54fba3..9c6ded7 100644 --- a/third_party/closure_compiler/externs/developer_private.js +++ b/third_party/closure_compiler/externs/developer_private.js
@@ -2,6 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// This file was generated by: +// tools/json_schema_compiler/compiler.py. +// NOTE: The format of types has changed. 'FooType' is now +// 'chrome.developerPrivate.FooType'. +// Please run the closure compiler before committing changes. +// See https://code.google.com/p/chromium/wiki/ClosureCompilation. + /** @fileoverview Externs generated from namespace: developerPrivate */ /** @@ -31,7 +38,7 @@ * }} * @see https://developer.chrome.com/extensions/developerPrivate#type-ItemInspectView */ -var ItemInspectView; +chrome.developerPrivate.ItemInspectView; /** * @typedef {{ @@ -42,7 +49,7 @@ * }} * @see https://developer.chrome.com/extensions/developerPrivate#type-InspectOptions */ -var InspectOptions; +chrome.developerPrivate.InspectOptions; /** * @typedef {{ @@ -50,7 +57,7 @@ * }} * @see https://developer.chrome.com/extensions/developerPrivate#type-InstallWarning */ -var InstallWarning; +chrome.developerPrivate.InstallWarning; /** * @enum {string} @@ -137,7 +144,7 @@ * }} * @see https://developer.chrome.com/extensions/developerPrivate#type-AccessModifier */ -var AccessModifier; +chrome.developerPrivate.AccessModifier; /** * @typedef {{ @@ -148,7 +155,7 @@ * }} * @see https://developer.chrome.com/extensions/developerPrivate#type-StackFrame */ -var StackFrame; +chrome.developerPrivate.StackFrame; /** * @typedef {{ @@ -163,7 +170,7 @@ * }} * @see https://developer.chrome.com/extensions/developerPrivate#type-ManifestError */ -var ManifestError; +chrome.developerPrivate.ManifestError; /** * @typedef {{ @@ -179,11 +186,11 @@ * renderViewId: number, * renderProcessId: number, * canInspect: boolean, - * stackTrace: !Array<StackFrame> + * stackTrace: !Array<!chrome.developerPrivate.StackFrame> * }} * @see https://developer.chrome.com/extensions/developerPrivate#type-RuntimeError */ -var RuntimeError; +chrome.developerPrivate.RuntimeError; /** * @typedef {{ @@ -193,7 +200,7 @@ * }} * @see https://developer.chrome.com/extensions/developerPrivate#type-DisableReasons */ -var DisableReasons; +chrome.developerPrivate.DisableReasons; /** * @typedef {{ @@ -202,7 +209,7 @@ * }} * @see https://developer.chrome.com/extensions/developerPrivate#type-OptionsPage */ -var OptionsPage; +chrome.developerPrivate.OptionsPage; /** * @typedef {{ @@ -211,7 +218,7 @@ * }} * @see https://developer.chrome.com/extensions/developerPrivate#type-HomePage */ -var HomePage; +chrome.developerPrivate.HomePage; /** * @typedef {{ @@ -224,10 +231,11 @@ * }} * @see https://developer.chrome.com/extensions/developerPrivate#type-ExtensionView */ -var ExtensionView; +chrome.developerPrivate.ExtensionView; /** * @enum {string} + * @see https://developer.chrome.com/extensions/developerPrivate#type-ControllerType */ chrome.developerPrivate.ControllerType = { POLICY: 'POLICY', @@ -240,8 +248,9 @@ * type: !chrome.developerPrivate.ControllerType, * text: string * }} + * @see https://developer.chrome.com/extensions/developerPrivate#type-ControlledInfo */ -var ControlledInfo; +chrome.developerPrivate.ControlledInfo; /** * @typedef {{ @@ -254,47 +263,47 @@ * }} * @see https://developer.chrome.com/extensions/developerPrivate#type-Command */ -var Command; +chrome.developerPrivate.Command; /** * @typedef {{ * actionButtonHidden: boolean, * blacklistText: (string|undefined), - * commands: !Array<Command>, - * controlledInfo: (ControlledInfo|undefined), + * commands: !Array<!chrome.developerPrivate.Command>, + * controlledInfo: (!chrome.developerPrivate.ControlledInfo|undefined), * dependentExtensions: !Array<string>, * description: string, - * disableReasons: DisableReasons, - * errorCollection: AccessModifier, - * fileAccess: AccessModifier, - * homePage: HomePage, + * disableReasons: !chrome.developerPrivate.DisableReasons, + * errorCollection: !chrome.developerPrivate.AccessModifier, + * fileAccess: !chrome.developerPrivate.AccessModifier, + * homePage: !chrome.developerPrivate.HomePage, * iconUrl: string, * id: string, - * incognitoAccess: AccessModifier, + * incognitoAccess: !chrome.developerPrivate.AccessModifier, * installWarnings: !Array<string>, * launchUrl: (string|undefined), * location: !chrome.developerPrivate.Location, * locationText: (string|undefined), - * manifestErrors: !Array<ManifestError>, + * manifestErrors: !Array<!chrome.developerPrivate.ManifestError>, * mustRemainInstalled: boolean, * name: string, * offlineEnabled: boolean, - * optionsPage: (OptionsPage|undefined), + * optionsPage: (!chrome.developerPrivate.OptionsPage|undefined), * path: (string|undefined), * prettifiedPath: (string|undefined), - * runOnAllUrls: AccessModifier, - * runtimeErrors: !Array<RuntimeError>, + * runOnAllUrls: !chrome.developerPrivate.AccessModifier, + * runtimeErrors: !Array<!chrome.developerPrivate.RuntimeError>, * runtimeWarnings: !Array<string>, * state: !chrome.developerPrivate.ExtensionState, * type: !chrome.developerPrivate.ExtensionType, * updateUrl: string, * userMayModify: boolean, * version: string, - * views: !Array<ExtensionView> + * views: !Array<!chrome.developerPrivate.ExtensionView> * }} * @see https://developer.chrome.com/extensions/developerPrivate#type-ExtensionInfo */ -var ExtensionInfo; +chrome.developerPrivate.ExtensionInfo; /** * @typedef {{ @@ -306,7 +315,7 @@ * }} * @see https://developer.chrome.com/extensions/developerPrivate#type-ProfileInfo */ -var ProfileInfo; +chrome.developerPrivate.ProfileInfo; /** * @typedef {{ @@ -332,15 +341,15 @@ * app_launch_url: (string|undefined), * homepage_url: (string|undefined), * update_url: (string|undefined), - * install_warnings: !Array<InstallWarning>, + * install_warnings: !Array<!chrome.developerPrivate.InstallWarning>, * manifest_errors: !Array<*>, * runtime_errors: !Array<*>, * offline_enabled: boolean, - * views: !Array<ItemInspectView> + * views: !Array<!chrome.developerPrivate.ItemInspectView> * }} * @see https://developer.chrome.com/extensions/developerPrivate#type-ItemInfo */ -var ItemInfo; +chrome.developerPrivate.ItemInfo; /** * @typedef {{ @@ -349,7 +358,7 @@ * }} * @see https://developer.chrome.com/extensions/developerPrivate#type-GetExtensionsInfoOptions */ -var GetExtensionsInfoOptions; +chrome.developerPrivate.GetExtensionsInfoOptions; /** * @typedef {{ @@ -362,7 +371,7 @@ * }} * @see https://developer.chrome.com/extensions/developerPrivate#type-ExtensionConfigurationUpdate */ -var ExtensionConfigurationUpdate; +chrome.developerPrivate.ExtensionConfigurationUpdate; /** * @typedef {{ @@ -370,7 +379,7 @@ * }} * @see https://developer.chrome.com/extensions/developerPrivate#type-ProfileConfigurationUpdate */ -var ProfileConfigurationUpdate; +chrome.developerPrivate.ProfileConfigurationUpdate; /** * @typedef {{ @@ -381,7 +390,7 @@ * }} * @see https://developer.chrome.com/extensions/developerPrivate#type-ExtensionCommandUpdate */ -var ExtensionCommandUpdate; +chrome.developerPrivate.ExtensionCommandUpdate; /** * @typedef {{ @@ -389,7 +398,7 @@ * }} * @see https://developer.chrome.com/extensions/developerPrivate#type-ReloadOptions */ -var ReloadOptions; +chrome.developerPrivate.ReloadOptions; /** * @typedef {{ @@ -397,7 +406,7 @@ * }} * @see https://developer.chrome.com/extensions/developerPrivate#type-LoadUnpackedOptions */ -var LoadUnpackedOptions; +chrome.developerPrivate.LoadUnpackedOptions; /** * @enum {string} @@ -454,7 +463,7 @@ * }} * @see https://developer.chrome.com/extensions/developerPrivate#type-PackDirectoryResponse */ -var PackDirectoryResponse; +chrome.developerPrivate.PackDirectoryResponse; /** * @typedef {{ @@ -462,17 +471,17 @@ * }} * @see https://developer.chrome.com/extensions/developerPrivate#type-ProjectInfo */ -var ProjectInfo; +chrome.developerPrivate.ProjectInfo; /** * @typedef {{ * event_type: !chrome.developerPrivate.EventType, * item_id: string, - * extensionInfo: (ExtensionInfo|undefined) + * extensionInfo: (!chrome.developerPrivate.ExtensionInfo|undefined) * }} * @see https://developer.chrome.com/extensions/developerPrivate#type-EventData */ -var EventData; +chrome.developerPrivate.EventData; /** * @typedef {{ @@ -485,7 +494,7 @@ * }} * @see https://developer.chrome.com/extensions/developerPrivate#type-RequestFileSourceProperties */ -var RequestFileSourceProperties; +chrome.developerPrivate.RequestFileSourceProperties; /** * @typedef {{ @@ -497,7 +506,7 @@ * }} * @see https://developer.chrome.com/extensions/developerPrivate#type-RequestFileSourceResponse */ -var RequestFileSourceResponse; +chrome.developerPrivate.RequestFileSourceResponse; /** * @typedef {{ @@ -511,7 +520,7 @@ * }} * @see https://developer.chrome.com/extensions/developerPrivate#type-OpenDevToolsProperties */ -var OpenDevToolsProperties; +chrome.developerPrivate.OpenDevToolsProperties; /** * @typedef {{ @@ -521,7 +530,7 @@ * }} * @see https://developer.chrome.com/extensions/developerPrivate#type-DeleteExtensionErrorsProperties */ -var DeleteExtensionErrorsProperties; +chrome.developerPrivate.DeleteExtensionErrorsProperties; /** * Runs auto update for extensions and apps immediately. @@ -533,10 +542,10 @@ /** * Returns information of all the extensions and apps installed. - * @param {GetExtensionsInfoOptions=} options Options to restrict the items - * returned. - * @param {function(!Array<ExtensionInfo>):void=} callback Called with - * extensions info. + * @param {!chrome.developerPrivate.GetExtensionsInfoOptions=} options Options + * to restrict the items returned. + * @param {function(!Array<!chrome.developerPrivate.ExtensionInfo>):void=} callback Called with extensions + * info. * @see https://developer.chrome.com/extensions/developerPrivate#method-getExtensionsInfo */ chrome.developerPrivate.getExtensionsInfo = function(options, callback) {}; @@ -544,7 +553,8 @@ /** * Returns information of a particular extension. * @param {string} id The id of the extension. - * @param {function(ExtensionInfo):void=} callback Called with the result. + * @param {function(!chrome.developerPrivate.ExtensionInfo):void=} callback + * Called with the result. * @see https://developer.chrome.com/extensions/developerPrivate#method-getExtensionInfo */ chrome.developerPrivate.getExtensionInfo = function(id, callback) {}; @@ -553,7 +563,8 @@ * Returns information of all the extensions and apps installed. * @param {boolean} includeDisabled include disabled items. * @param {boolean} includeTerminated include terminated items. - * @param {function(!Array<ItemInfo>):void} callback Called with items info. + * @param {function(!Array<!chrome.developerPrivate.ItemInfo>):void} callback + * Called with items info. * @deprecated Use getExtensionsInfo * @see https://developer.chrome.com/extensions/developerPrivate#method-getItemsInfo */ @@ -561,16 +572,16 @@ /** * Returns the current profile's configuration. - * @param {function(ProfileInfo):void} callback + * @param {function(!chrome.developerPrivate.ProfileInfo):void} callback * @see https://developer.chrome.com/extensions/developerPrivate#method-getProfileConfiguration */ chrome.developerPrivate.getProfileConfiguration = function(callback) {}; /** * Updates the active profile. - * @param {ProfileConfigurationUpdate} update The parameters for updating the - * profile's configuration. Any properties omitted from |update| will - * not be changed. + * @param {!chrome.developerPrivate.ProfileConfigurationUpdate} update The + * parameters for updating the profile's configuration. Any properties + * omitted from |update| will not be changed. * @param {function():void=} callback * @see https://developer.chrome.com/extensions/developerPrivate#method-updateProfileConfiguration */ @@ -587,7 +598,8 @@ /** * Reloads a given extension. * @param {string} extensionId The id of the extension to reload. - * @param {ReloadOptions=} options Additional configuration parameters. + * @param {!chrome.developerPrivate.ReloadOptions=} options Additional + * configuration parameters. * @param {function():void=} callback * @see https://developer.chrome.com/extensions/developerPrivate#method-reload */ @@ -595,9 +607,9 @@ /** * Modifies an extension's current configuration. - * @param {ExtensionConfigurationUpdate} update The parameters for updating the - * extension's configuration. Any properties omitted from |update| will - * not be changed. + * @param {!chrome.developerPrivate.ExtensionConfigurationUpdate} update The + * parameters for updating the extension's configuration. Any properties + * omitted from |update| will not be changed. * @param {function():void=} callback * @see https://developer.chrome.com/extensions/developerPrivate#method-updateExtensionConfiguration */ @@ -605,7 +617,8 @@ /** * Loads a user-selected unpacked item. - * @param {LoadUnpackedOptions=} options Additional configuration parameters. + * @param {!chrome.developerPrivate.LoadUnpackedOptions=} options Additional + * configuration parameters. * @param {function():void=} callback * @see https://developer.chrome.com/extensions/developerPrivate#method-loadUnpacked */ @@ -636,8 +649,8 @@ * @param {string} path * @param {string=} privateKeyPath The path of the private key, if one is given. * @param {number=} flags Special flags to apply to the loading process, if any. - * @param {function(PackDirectoryResponse):void=} callback called with the - * success result string. + * @param {function(!chrome.developerPrivate.PackDirectoryResponse):void=} callback called with the success result + * string. * @see https://developer.chrome.com/extensions/developerPrivate#method-packDirectory */ chrome.developerPrivate.packDirectory = function(path, privateKeyPath, flags, callback) {}; @@ -652,15 +665,15 @@ /** * Reads and returns the contents of a file related to an extension which caused * an error. - * @param {RequestFileSourceProperties} properties - * @param {function(RequestFileSourceResponse):void} callback + * @param {!chrome.developerPrivate.RequestFileSourceProperties} properties + * @param {function(!chrome.developerPrivate.RequestFileSourceResponse):void} callback * @see https://developer.chrome.com/extensions/developerPrivate#method-requestFileSource */ chrome.developerPrivate.requestFileSource = function(properties, callback) {}; /** * Open the developer tools to focus on a particular error. - * @param {OpenDevToolsProperties} properties + * @param {!chrome.developerPrivate.OpenDevToolsProperties} properties * @param {function():void=} callback * @see https://developer.chrome.com/extensions/developerPrivate#method-openDevTools */ @@ -668,8 +681,8 @@ /** * Delete reported extension erors. - * @param {DeleteExtensionErrorsProperties} properties The properties specifying - * the errors to remove. + * @param {!chrome.developerPrivate.DeleteExtensionErrorsProperties} properties + * The properties specifying the errors to remove. * @param {function():void=} callback * @see https://developer.chrome.com/extensions/developerPrivate#method-deleteExtensionErrors */ @@ -711,8 +724,8 @@ /** * Updates an extension command. - * @param {ExtensionCommandUpdate} update The parameters for updating the - * extension command. + * @param {!chrome.developerPrivate.ExtensionCommandUpdate} update The + * parameters for updating the extension command. * @param {function():void=} callback * @see https://developer.chrome.com/extensions/developerPrivate#method-updateExtensionCommand */ @@ -746,7 +759,7 @@ chrome.developerPrivate.allowFileAccess = function(extensionId, allow, callback) {}; /** - * @param {InspectOptions} options + * @param {!chrome.developerPrivate.InspectOptions} options * @param {function():void=} callback * @deprecated Use openDevTools * @see https://developer.chrome.com/extensions/developerPrivate#method-inspect
diff --git a/third_party/closure_compiler/runner/runner.jar b/third_party/closure_compiler/runner/runner.jar index 62c63547..c000f4d 100644 --- a/third_party/closure_compiler/runner/runner.jar +++ b/third_party/closure_compiler/runner/runner.jar Binary files differ
diff --git a/third_party/closure_compiler/runner/src/org/chromium/closure/compiler/ChromeCodingConvention.java b/third_party/closure_compiler/runner/src/org/chromium/closure/compiler/ChromeCodingConvention.java index 396ae82..7eadc53f 100644 --- a/third_party/closure_compiler/runner/src/org/chromium/closure/compiler/ChromeCodingConvention.java +++ b/third_party/closure_compiler/runner/src/org/chromium/closure/compiler/ChromeCodingConvention.java
@@ -67,4 +67,21 @@ new AssertInstanceofSpec("cr.ui.decorate") ); } + + // TODO(dbeam): combine this with ClosureCodingConvention? + @Override + public boolean isFunctionCallThatAlwaysThrows(Node n) { + if (n.isExprResult()) { + if (!n.getFirstChild().isCall()) { + return false; + } + } else if (!n.isCall()) { + return false; + } + if (n.isExprResult()) { + n = n.getFirstChild(); + } + // n is a call + return n.getFirstChild().matchesQualifiedName("assertNotReached"); + } }
diff --git a/third_party/opus/BUILD.gn b/third_party/opus/BUILD.gn index cc3d3cd..339ad967b 100644 --- a/third_party/opus/BUILD.gn +++ b/third_party/opus/BUILD.gn
@@ -18,6 +18,10 @@ config("opus_config") { include_dirs = [ "src/include" ] + + if (use_opus_fixed_point) { + defines = [ "OPUS_FIXED_POINT" ] + } } config("opus_test_config") {
diff --git a/tools/metrics/actions/extract_actions.py b/tools/metrics/actions/extract_actions.py index 218c8f2..320b3cf 100755 --- a/tools/metrics/actions/extract_actions.py +++ b/tools/metrics/actions/extract_actions.py
@@ -191,8 +191,8 @@ if match: # Plain call to RecordAction actions.add(match.group(1)) -def AddClosedSourceActions(actions): - """Add actions that are in code which is not checked out by default +def AddPDFPluginActions(actions): + """Add actions that are sent by the PDF plugin. Arguments actions: set of actions to add to. @@ -740,9 +740,9 @@ AddAutomaticResetBannerActions(actions) AddBookmarkManagerActions(actions) AddChromeOSActions(actions) - AddClosedSourceActions(actions) AddExtensionActions(actions) AddHistoryPageActions(actions) + AddPDFPluginActions(actions) return PrettyPrint(actions, actions_dict, comment_nodes)
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 38d7916..d8a960f 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -30916,6 +30916,14 @@ </summary> </histogram> +<histogram name="PDF.DocumentFeature" enum="PDFFeatures"> + <owner>tsergeant@chromium.org</owner> + <summary> + Tracks which features are used by documents opened in the PDF viewer, logged + when the document finishes loading. + </summary> +</histogram> + <histogram name="Pepper.InterfaceUsed" enum="PepperInterface"> <owner>mackinlay@google.com</owner> <owner>teravest@chromium.org</owner> @@ -68204,6 +68212,12 @@ <int value="3" label="Server failed"/> </enum> +<enum name="PDFFeatures" type="int"> + <int value="0" label="Loaded Document"/> + <int value="1" label="Has Title"/> + <int value="2" label="Has Bookmarks"/> +</enum> + <enum name="PeerConnectionCounters" type="int"> <int value="0" label="PeerConnection enabled with IPv4."/> <int value="1" label="PeerConnection enabled with Ipv6."/>
diff --git a/tools/perf/core/test_data/__init__.py b/tools/perf/core/test_data/__init__.py new file mode 100644 index 0000000..50b23df --- /dev/null +++ b/tools/perf/core/test_data/__init__.py
@@ -0,0 +1,3 @@ +# 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.
diff --git a/tools/perf/core/test_data/complex_benchmarks_case.py b/tools/perf/core/test_data/complex_benchmarks_case.py index 14236819..4226b22f 100644 --- a/tools/perf/core/test_data/complex_benchmarks_case.py +++ b/tools/perf/core/test_data/complex_benchmarks_case.py
@@ -4,7 +4,7 @@ from core import perf_benchmark -import simple_benchmarks_case +from core.test_data import simple_benchmarks_case class TestBenchmarkComplexFoo(perf_benchmark.PerfBenchmark):
diff --git a/tools/telemetry/telemetry/internal/backends/chrome/android_browser_backend.py b/tools/telemetry/telemetry/internal/backends/chrome/android_browser_backend.py index 177268a..fcff75a 100644 --- a/tools/telemetry/telemetry/internal/backends/chrome/android_browser_backend.py +++ b/tools/telemetry/telemetry/internal/backends/chrome/android_browser_backend.py
@@ -167,6 +167,12 @@ args.append('--enable-remote-debugging') args.append('--disable-fre') args.append('--disable-external-intent-requests') + + trace_config_file = (self.platform_backend.tracing_controller_backend + .GetChromeTraceConfigFile()) + if trace_config_file: + args.append('--trace-config-file=%s' % trace_config_file) + return args @property
diff --git a/tools/valgrind/gtest_exclude/remoting_unittests.gtest_mac.txt b/tools/valgrind/gtest_exclude/remoting_unittests.gtest_mac.txt deleted file mode 100644 index 585b98401..0000000 --- a/tools/valgrind/gtest_exclude/remoting_unittests.gtest_mac.txt +++ /dev/null
@@ -1,2 +0,0 @@ -# Failing on Mac. https://crbug.com/543431 -JingleSessionTest.TestQuicStreamChannel
diff --git a/tools/valgrind/memcheck/suppressions.txt b/tools/valgrind/memcheck/suppressions.txt index 0a61f5d0..74a858f 100644 --- a/tools/valgrind/memcheck/suppressions.txt +++ b/tools/valgrind/memcheck/suppressions.txt
@@ -538,32 +538,6 @@ fun:_ZN7content45ManifestParserTest_IconDensityParseRules_Test8TestBodyEv } { - bug_484444 - Memcheck:Leak - fun:_Znw* - ... - fun:_ZN4mojo7BindingINS_15ServiceProviderEE4BindENS_16ScopedHandleBaseINS_17MessagePipeHandleEEEPK15MojoAsyncWaiter - fun:_ZN4mojo7BindingINS_15ServiceProviderEE4BindENS_16InterfaceRequestIS1_EEPK15MojoAsyncWaiter - fun:_ZN7content19ServiceRegistryImpl4BindEN4mojo16InterfaceRequestINS1_15ServiceProviderEEE -} -{ - bug_484444b - Memcheck:Leak - fun:_Znw* - fun:_ZN4mojo8internal11FilterChain6AppendINS0_22MessageHeaderValidatorEEEvv - fun:_ZN4mojo8internal17InterfacePtrStateINS_15ServiceProviderEE25ConfigureProxyIfNecessaryEv - fun:_ZN4mojo8internal17InterfacePtrStateINS_15ServiceProviderEE8instanceEv -} -{ - bug_484444c - Memcheck:Leak - fun:_Znw* - fun:_ZN4mojo8internal10SharedDataIPNS0_6RouterEEC2ERKS3_ - fun:_ZN4mojo8internal6RouterC1ENS_16ScopedHandleBaseINS_17MessagePipeHandleEEENS0_11FilterChainEPK15MojoAsyncWaiter - fun:_ZN4mojo8internal17InterfacePtrStateINS_15ServiceProviderEE25ConfigureProxyIfNecessaryEv - fun:_ZN4mojo8internal17InterfacePtrStateINS_15ServiceProviderEE8instanceEv -} -{ bug_512466 Memcheck:Leak fun:_Znw* @@ -2464,7 +2438,7 @@ fun:_ZN5blink4Heap19checkAndMarkPointerEPNS_7VisitorEPh fun:_ZN5blink11ThreadState10visitStackEPNS_7VisitorE ... - fun:_ZN5blink4Heap14collectGarbageENS_11ThreadState10StackState* + fun:_ZN5blink4Heap14collectGarbageENS_7BlinkGC10StackState* } { bug_342591 @@ -2611,41 +2585,6 @@ fun:_ZN3WTFL18callFunctionObjectEPv } { - bug_367809_a - Memcheck:Leak - fun:_Znw* - fun:_ZN4mojo6common13HandleWatcher5StartERKNS_6HandleEjmRKN4base8CallbackIFviEEE - fun:_ZN4mojo8internal12_GLOBAL__N_19AsyncWaitEP15MojoAsyncWaiterjjmPFvPviES4_ - fun:_ZN4mojo8internal9Connector14WaitToReadMoreEv - fun:_ZN4mojo8internal9ConnectorC1ENS_16ScopedHandleBaseINS_17MessagePipeHandleEEEP15MojoAsyncWaiter - fun:_ZN4mojo8internal6RouterC1ENS_16ScopedHandleBaseINS_17MessagePipeHandleEEEP15MojoAsyncWaiter - fun:_ZN4mojo9RemotePtrINS_11ShellClientEE5StateC1ENS_16ScopedHandleBaseINS_17MessagePipeHandleEEEPNS_5ShellEPNS_12ErrorHandlerEP15MojoAsyncWaiter - fun:_ZN4mojo9RemotePtrINS_11ShellClientEE5resetENS_16ScopedHandleBaseINS_15InterfaceHandleIS1_EEEEPNS_5ShellEPNS_12ErrorHandlerEP15MojoAsyncWaiter - fun:_ZN7content19MojoApplicationHost4InitEv -} -{ - bug_367809_b - Memcheck:Leak - fun:_Znw* - fun:_ZN4mojo8internal12_GLOBAL__N_19AsyncWaitEP15MojoAsyncWaiterjjmPFvPviES4_ - fun:_ZN4mojo8internal9Connector14WaitToReadMoreEv - fun:_ZN4mojo8internal9ConnectorC1ENS_16ScopedHandleBaseINS_17MessagePipeHandleEEEP15MojoAsyncWaiter - fun:_ZN4mojo8internal6RouterC1ENS_16ScopedHandleBaseINS_17MessagePipeHandleEEEP15MojoAsyncWaiter - fun:_ZN4mojo9RemotePtrINS_11ShellClientEE5StateC1ENS_16ScopedHandleBaseINS_17MessagePipeHandleEEEPNS_5ShellEPNS_12ErrorHandlerEP15MojoAsyncWaiter - fun:_ZN4mojo9RemotePtrINS_11ShellClientEE5resetENS_16ScopedHandleBaseINS_15InterfaceHandleIS1_EEEEPNS_5ShellEPNS_12ErrorHandlerEP15MojoAsyncWaiter - fun:_ZN7content19MojoApplicationHost4InitEv -} -{ - bug_367809_c - Memcheck:Leak - fun:_Znw* - fun:_ZN4mojo8internal10SharedDataIPNS0_6RouterEEC1ERKS3_ - fun:_ZN4mojo8internal6RouterC1ENS_16ScopedHandleBaseINS_17MessagePipeHandleEEEP15MojoAsyncWaiter - fun:_ZN4mojo9RemotePtrINS_11ShellClientEE5StateC1ENS_16ScopedHandleBaseINS_17MessagePipeHandleEEEPNS_5ShellEPNS_12ErrorHandlerEP15MojoAsyncWaiter - fun:_ZN4mojo9RemotePtrINS_11ShellClientEE5resetENS_16ScopedHandleBaseINS_15InterfaceHandleIS1_EEEEPNS_5ShellEPNS_12ErrorHandlerEP15MojoAsyncWaiter - fun:_ZN7content19MojoApplicationHost4InitEv -} -{ bug_367809_d Memcheck:Leak fun:_Znw* @@ -2679,55 +2618,6 @@ fun:_ZN7testing8internal15TestFactoryImplIN8feedback* } { - bug_372487_a - Memcheck:Leak - fun:_Znw* - ... - fun:_ZN4mojo10BindToPipeIN7content19MojoApplicationHost9ShellImplEEEPT_S5_NS_16ScopedHandleBaseINS_17MessagePipeHandleEEEP15MojoAsyncWaiter - fun:_ZN7content19MojoApplicationHost4InitEv - fun:_ZN7content21RenderProcessHostImpl4InitEv - fun:_ZN7content18RenderViewHostImpl16CreateRenderViewERKSbItN4base20string16_char_traitsESaItEEiib - fun:_ZN7content15WebContentsImpl32CreateRenderViewForRenderManagerEPNS_14RenderViewHostEiPNS_26CrossProcessFrameConnectorE - fun:_ZN7content22RenderFrameHostManager14InitRenderViewEPNS_14RenderViewHostEi - fun:_ZN7content22RenderFrameHostManager8NavigateERKNS_19NavigationEntryImplE - fun:_ZN7content13NavigatorImpl15NavigateToEntryEPNS_19RenderFrameHostImplERKNS_19NavigationEntryImplENS_20NavigationController10ReloadTypeE - fun:_ZN7content13NavigatorImpl22NavigateToPendingEntryEPNS_19RenderFrameHostImplENS_20NavigationController10ReloadTypeE - fun:_ZN7content15WebContentsImpl22NavigateToPendingEntryENS_20NavigationController10ReloadTypeE - fun:_ZN7content24NavigationControllerImpl22NavigateToPendingEntryENS_20NavigationController10ReloadTypeE - fun:_ZN7content24NavigationControllerImpl9LoadEntryEPNS_19NavigationEntryImplE - fun:_ZN7content24NavigationControllerImpl17LoadURLWithParamsERKNS_20NavigationController13LoadURLParamsE - fun:_ZN7content5Shell15LoadURLForFrameERK4GURLRKSs - fun:_ZN7content5Shell7LoadURLERK4GURL - fun:_ZN7content19BlinkTestController20PrepareForLayoutTestERK4GURLRKN4base8FilePathEbRKSs - fun:_ZN12_GLOBAL__N_110RunOneTestERKSsPbRK10scoped_ptrIN7content17BrowserMainRunnerEN4base14DefaultDeleterIS5_EEE - fun:_Z16ShellBrowserMainRKN7content18MainFunctionParamsERK10scoped_ptrINS_17BrowserMainRunnerEN4base14DefaultDeleterIS4_EEE - fun:_ZN7content17ShellMainDelegate10RunProcessERKSsRKNS_18MainFunctionParamsE - fun:_ZN7content23RunNamedProcessTypeMainERKSsRKNS_18MainFunctionParamsEPNS_19ContentMainDelegateE -} -{ - bug_372487_b - Memcheck:Leak - fun:_Znw* - ... - fun:_ZN4mojo8internal6RouterC1ENS_16ScopedHandleBaseINS_17MessagePipeHandleEEEP15MojoAsyncWaiter - fun:_ZN4mojo8internal18InterfaceImplStateINS_5ShellEE4BindENS_16ScopedHandleBaseINS_17MessagePipeHandleEEEP15MojoAsyncWaiter - fun:_ZN4mojo10BindToPipeIN7content19MojoApplicationHost9ShellImplEEEPT_S5_NS_16ScopedHandleBaseINS_17MessagePipeHandleEEEP15MojoAsyncWaiter - fun:_ZN7content19MojoApplicationHost4InitEv - fun:_ZN7content21RenderProcessHostImpl4InitEv - fun:_ZN7content18RenderViewHostImpl16CreateRenderViewERKSbItN4base20string16_char_traitsESaItEEiib - fun:_ZN7content15WebContentsImpl32CreateRenderViewForRenderManagerEPNS_14RenderViewHostEiPNS_26CrossProcessFrameConnectorE - fun:_ZN7content22RenderFrameHostManager14InitRenderViewEPNS_14RenderViewHostEi - fun:_ZN7content22RenderFrameHostManager8NavigateERKNS_19NavigationEntryImplE - fun:_ZN7content13NavigatorImpl15NavigateToEntryEPNS_19RenderFrameHostImplERKNS_19NavigationEntryImplENS_20NavigationController10ReloadTypeE - fun:_ZN7content13NavigatorImpl22NavigateToPendingEntryEPNS_19RenderFrameHostImplENS_20NavigationController10ReloadTypeE - fun:_ZN7content15WebContentsImpl22NavigateToPendingEntryENS_20NavigationController10ReloadTypeE - fun:_ZN7content24NavigationControllerImpl22NavigateToPendingEntryENS_20NavigationController10ReloadTypeE - fun:_ZN7content24NavigationControllerImpl9LoadEntryEPNS_19NavigationEntryImplE - fun:_ZN7content24NavigationControllerImpl17LoadURLWithParamsERKNS_20NavigationController13LoadURLParamsE - fun:_ZN7content5Shell15LoadURLForFrameERK4GURLRKSs - fun:_ZN7content5Shell7LoadURLERK4GURL -} -{ bug_379943 Memcheck:Leak fun:_Znw* @@ -3282,24 +3172,6 @@ fun:_ZN4base12_GLOBAL__N_110ThreadFuncEPv } { - bug_455732 - Memcheck:Leak - fun:_Znw* - ... - fun:_ZN7content12_GLOBAL__N_120ApplicationSetupImpl24ExchangeServiceProvidersEN4mojo16InterfaceRequestINS2_15ServiceProviderEEENS2_12InterfacePtrIS4_EE - fun:_ZN7content20ApplicationSetupStub6AcceptEPN4mojo7MessageE - fun:_ZN4mojo8internal6Router21HandleIncomingMessageEPNS_7MessageE - fun:_ZN4mojo8internal6Router26HandleIncomingMessageThunk6AcceptEPNS_7MessageE - fun:_ZN7content32ApplicationSetupRequestValidator6AcceptEPN4mojo7MessageE - fun:_ZN4mojo8internal22MessageHeaderValidator6AcceptEPNS_7MessageE - fun:_ZN4mojo22ReadAndDispatchMessageENS_17MessagePipeHandleEPNS_15MessageReceiverEPb - fun:_ZN4mojo8internal9Connector17ReadSingleMessageEPi - fun:_ZN4mojo8internal9Connector24ReadAllAvailableMessagesEv - fun:_ZN4mojo8internal9Connector13OnHandleReadyEi - fun:_ZN4mojo8internal9Connector17CallOnHandleReadyEPvi - fun:_ZN4mojo8internal12_GLOBAL__N_113OnHandleReadyEPNS_6common13HandleWatcherEPFvPviES5_i -} -{ bug_476940 Memcheck:Leak fun:malloc @@ -3405,7 +3277,7 @@ fun:_ZN5blink13CallbackStack4Item4callEPNS_7VisitorE fun:_ZN5blink4Heap25popAndInvokeTraceCallbackEPNS_7VisitorE fun:_ZN5blink4Heap19processMarkingStackEPNS_7VisitorE - fun:_ZN5blink4Heap14collectGarbageENS_11ThreadState10StackStateENS1_6GCTypeENS0_8GCReasonE + fun:_ZN5blink4Heap14collectGarbageENS_7BlinkGC10StackStateENS1_6GCTypeENS0_8GCReasonE fun:_ZN5blink14V8GCController10gcEpilogueEN2v86GCTypeENS1_15GCCallbackFlagsE fun:_ZN2v88internal4Heap23CallGCEpilogueCallbacksENS_6GCTypeENS_15GCCallbackFlagsE fun:_ZN2v88internal4Heap24PerformGarbageCollectionENS0_16GarbageCollectorENS_15GCCallbackFlagsE @@ -3504,26 +3376,6 @@ fun:_ZN7content5Shell15LoadURLForFrameERK4GURLRKSs } { - bug_536907_b - Memcheck:Leak - fun:_Znw* - ... - fun:_ZNSt3mapISsN4base8CallbackIFvN4mojo16ScopedHandleBaseINS2_17MessagePipeHandleEEEEEESt4lessISsESaISt4pairIKSsS7_EEEixERSB_ - fun:_ZN7content19ServiceRegistryImpl10AddServiceERKSsN4base8CallbackIFvN4mojo16ScopedHandleBaseINS5_17MessagePipeHandleEEEEEE - fun:_ZN7content15ServiceRegistry10AddServiceIN6device14BatteryMonitorEEEvN4base8CallbackIFvN4mojo16InterfaceRequestIT_EEEEE - fun:_ZN7content21RenderProcessHostImpl20RegisterMojoServicesEv - fun:_ZN7content21RenderProcessHostImpl4InitEv - fun:_ZN7content22RenderFrameHostManager14InitRenderViewEPNS_18RenderViewHostImplEi - fun:_ZN7content22RenderFrameHostManager8NavigateERK4GURLRKNS_20FrameNavigationEntryERKNS_19NavigationEntryImplE - fun:_ZN7content13NavigatorImpl15NavigateToEntryEPNS_13FrameTreeNodeERKNS_20FrameNavigationEntryERKNS_19NavigationEntryImplENS_20NavigationController10ReloadTypeEb - fun:_ZN7content13NavigatorImpl22NavigateToPendingEntryEPNS_13FrameTreeNodeERKNS_20FrameNavigationEntryENS_20NavigationController10ReloadTypeEb - fun:_ZN7content24NavigationControllerImpl30NavigateToPendingEntryInternalENS_20NavigationController10ReloadTypeE - fun:_ZN7content24NavigationControllerImpl22NavigateToPendingEntryENS_20NavigationController10ReloadTypeE - fun:_ZN7content24NavigationControllerImpl9LoadEntryE10scoped_ptrINS_19NavigationEntryImplEN4base14DefaultDeleterIS2_EEE - fun:_ZN7content24NavigationControllerImpl17LoadURLWithParamsERKNS_20NavigationController13LoadURLParamsE - fun:_ZN7content5Shell15LoadURLForFrameERK4GURLRKSs -} -{ bug_542543 Memcheck:Leak fun:_Znw*
diff --git a/tools/vim/ninja_output.py b/tools/vim/ninja_output.py index a2d1268..fab26eb 100644 --- a/tools/vim/ninja_output.py +++ b/tools/vim/ninja_output.py
@@ -45,7 +45,9 @@ if os.path.isdir(out): output_dirs.append(os.path.relpath(out, start = chrome_root)) - configs = [configuration] if configuration else ['Debug', 'Release'] + configs = ['Debug', 'Release', 'Default'] + if configuration: + configs = [configuration] def generate_paths(): for out_dir, config in itertools.product(output_dirs, configs):
diff --git a/ui/base/BUILD.gn b/ui/base/BUILD.gn index 6fad1dc..9a1e225 100644 --- a/ui/base/BUILD.gn +++ b/ui/base/BUILD.gn
@@ -127,6 +127,7 @@ "hit_test.h", "idle/idle.cc", "idle/idle.h", + "idle/idle_android.cc", "idle/idle_chromeos.cc", "idle/idle_linux.cc", "idle/idle_mac.mm", @@ -570,10 +571,14 @@ } if (is_android || is_ios) { + sources -= [ "device_form_factor_desktop.cc" ] + } + + if ((is_android && !use_aura) || is_ios) { sources -= [ - "device_form_factor_desktop.cc", "idle/idle.cc", "idle/idle.h", + "idle/idle_android.cc", ] } }
diff --git a/ui/base/idle/idle_android.cc b/ui/base/idle/idle_android.cc new file mode 100644 index 0000000..43b27c0 --- /dev/null +++ b/ui/base/idle/idle_android.cc
@@ -0,0 +1,21 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/base/idle/idle.h" + +#include "base/logging.h" + +namespace ui { + +void CalculateIdleTime(IdleTimeCallback notify) { + NOTIMPLEMENTED(); + notify.Run(0); +} + +bool CheckIdleStateIsLocked() { + NOTIMPLEMENTED(); + return false; +} + +} // namespace ui
diff --git a/ui/base/ui_base.gyp b/ui/base/ui_base.gyp index 487d2b3..417599e 100644 --- a/ui/base/ui_base.gyp +++ b/ui/base/ui_base.gyp
@@ -198,6 +198,7 @@ 'hit_test.h', 'idle/idle.cc', 'idle/idle.h', + 'idle/idle_android.cc', 'idle/idle_chromeos.cc', 'idle/idle_linux.cc', 'idle/idle_mac.mm', @@ -584,8 +585,6 @@ 'default_theme_provider.cc', 'dragdrop/drag_utils.cc', 'dragdrop/drag_utils.h', - 'idle/idle.cc', - 'idle/idle.h', 'l10n/l10n_font_util.cc', 'models/button_menu_item_model.cc', 'models/dialog_model.cc', @@ -606,7 +605,10 @@ }], ['OS=="android" and use_aura==0', { 'sources!': [ - 'cursor/cursor_android.cc' + 'cursor/cursor_android.cc', + 'idle/idle.cc', + 'idle/idle.h', + 'idle/idle_android.cc', ], }], ['OS=="android" and use_aura==1', {
diff --git a/ui/compositor/callback_layer_animation_observer.cc b/ui/compositor/callback_layer_animation_observer.cc index 305bce6..639caf4 100644 --- a/ui/compositor/callback_layer_animation_observer.cc +++ b/ui/compositor/callback_layer_animation_observer.cc
@@ -4,22 +4,39 @@ #include "ui/compositor/callback_layer_animation_observer.h" +#include "base/bind.h" #include "ui/compositor/layer_animation_sequence.h" namespace ui { +void CallbackLayerAnimationObserver::DummyAnimationStartedCallback( + const CallbackLayerAnimationObserver&) {} + +bool CallbackLayerAnimationObserver::DummyAnimationEndedCallback( + bool should_delete_observer, + const CallbackLayerAnimationObserver&) { + return should_delete_observer; +} + CallbackLayerAnimationObserver::CallbackLayerAnimationObserver( AnimationStartedCallback animation_started_callback, AnimationEndedCallback animation_ended_callback) - : active_(false), - attached_sequence_count_(0), - detached_sequence_count_(0), - started_count_(0), - aborted_count_(0), - successful_count_(0), - animation_started_callback_(animation_started_callback), - animation_ended_callback_(animation_ended_callback), - destroyed_(nullptr) {} + : animation_started_callback_(animation_started_callback), + animation_ended_callback_(animation_ended_callback) {} + +CallbackLayerAnimationObserver::CallbackLayerAnimationObserver( + AnimationStartedCallback animation_started_callback, + bool should_delete_observer) + : animation_started_callback_(animation_started_callback), + animation_ended_callback_(base::Bind( + &CallbackLayerAnimationObserver::DummyAnimationEndedCallback, + should_delete_observer)) {} + +CallbackLayerAnimationObserver::CallbackLayerAnimationObserver( + AnimationEndedCallback animation_ended_callback) + : animation_started_callback_(base::Bind( + &CallbackLayerAnimationObserver::DummyAnimationStartedCallback)), + animation_ended_callback_(animation_ended_callback) {} CallbackLayerAnimationObserver::~CallbackLayerAnimationObserver() { if (destroyed_)
diff --git a/ui/compositor/callback_layer_animation_observer.h b/ui/compositor/callback_layer_animation_observer.h index 236f1a2..cff5fb4 100644 --- a/ui/compositor/callback_layer_animation_observer.h +++ b/ui/compositor/callback_layer_animation_observer.h
@@ -69,9 +69,44 @@ typedef base::Callback<bool(const CallbackLayerAnimationObserver&)> AnimationEndedCallback; + // A dummy no-op AnimationStartedCallback. + static void DummyAnimationStartedCallback( + const CallbackLayerAnimationObserver&); + + // A dummy no-op AnimationEndedCallback that will return + // |should_delete_observer|. + // + // Example usage: + // + // ui::CallbackLayerAnimationObserver* animation_observer = + // new ui::CallbackLayerAnimationObserver( + // base::Bind(&ui::CallbackLayerAnimationObserver:: + // DummyAnimationStartedCallback), + // base::Bind(&ui::CallbackLayerAnimationObserver:: + // DummyAnimationEndedCallback, false)); + static bool DummyAnimationEndedCallback( + bool should_delete_observer, + const CallbackLayerAnimationObserver&); + + // Create an instance that will invoke the |animation_started_callback| when + // the animation has started and the |animation_ended_callback| when the + // animation has ended. CallbackLayerAnimationObserver( AnimationStartedCallback animation_started_callback, AnimationEndedCallback animation_ended_callback); + + // Create an instance that will invoke the |animation_started_callback| when + // the animation has started and will delete |this| when the animations have + // ended if |should_delete_observer| is true. + CallbackLayerAnimationObserver( + AnimationStartedCallback animation_started_callback, + bool should_delete_observer); + + // Create an instance that will invoke the |animation_ended_callback| when the + // animations have ended. + explicit CallbackLayerAnimationObserver( + AnimationEndedCallback animation_ended_callback); + ~CallbackLayerAnimationObserver() override; bool active() const { return active_; } @@ -108,22 +143,22 @@ void CheckAllSequencesCompleted(); // Allows the callbacks to be invoked when true. - bool active_; + bool active_ = false; // The total number of animation sequences that have been attached. - int attached_sequence_count_; + int attached_sequence_count_ = 0; // The total number of animation sequences that have been detached. - int detached_sequence_count_; + int detached_sequence_count_ = 0; // The number of animation sequences that have been started. - int started_count_; + int started_count_ = 0; // The number of animation sequences that were aborted. - int aborted_count_; + int aborted_count_ = 0; // The number of animation sequences that completed successfully. - int successful_count_; + int successful_count_ = 0; // The callback to invoke once all the animation sequences have been started. AnimationStartedCallback animation_started_callback_; @@ -133,7 +168,7 @@ // Set to true in the destructor (if non-NULL). Used to detect deletion while // calling out. - bool* destroyed_; + bool* destroyed_ = nullptr; DISALLOW_COPY_AND_ASSIGN(CallbackLayerAnimationObserver); };
diff --git a/ui/compositor/callback_layer_animation_observer_unittest.cc b/ui/compositor/callback_layer_animation_observer_unittest.cc index b5d708fb..f42f561 100644 --- a/ui/compositor/callback_layer_animation_observer_unittest.cc +++ b/ui/compositor/callback_layer_animation_observer_unittest.cc
@@ -154,6 +154,16 @@ AnimationStartedCallback animation_started_callback, AnimationEndedCallback animation_ended_callback, bool* destroyed); + + TestCallbackLayerAnimationObserver( + AnimationStartedCallback animation_started_callback, + bool should_delete_observer, + bool* destroyed); + + TestCallbackLayerAnimationObserver( + AnimationEndedCallback animation_ended_callback, + bool* destroyed); + ~TestCallbackLayerAnimationObserver() override; private: @@ -169,11 +179,33 @@ : CallbackLayerAnimationObserver(animation_started_callback, animation_ended_callback), destroyed_(destroyed) { - (*destroyed_) = false; + if (destroyed_) + (*destroyed_) = false; +} + +TestCallbackLayerAnimationObserver::TestCallbackLayerAnimationObserver( + AnimationStartedCallback animation_started_callback, + bool should_delete_observer, + bool* destroyed) + : CallbackLayerAnimationObserver(animation_started_callback, + should_delete_observer), + destroyed_(destroyed) { + if (destroyed_) + (*destroyed_) = false; +} + +TestCallbackLayerAnimationObserver::TestCallbackLayerAnimationObserver( + AnimationEndedCallback animation_ended_callback, + bool* destroyed) + : CallbackLayerAnimationObserver(animation_ended_callback), + destroyed_(destroyed) { + if (destroyed_) + (*destroyed_) = false; } TestCallbackLayerAnimationObserver::~TestCallbackLayerAnimationObserver() { - (*destroyed_) = true; + if (destroyed_) + (*destroyed_) = true; } class CallbackLayerAnimationObserverTest : public testing::Test { @@ -224,13 +256,37 @@ return sequence; } -TEST_F(CallbackLayerAnimationObserverTest, VerifyInitialState) { - EXPECT_FALSE(observer_->active()); - EXPECT_EQ(0, observer_->aborted_count()); - EXPECT_EQ(0, observer_->successful_count()); +TEST(CallbackLayerAnimationObserverDestructionTest, VerifyFalseAutoDelete) { + TestCallbacks callbacks; + callbacks.set_should_delete_observer_on_animations_ended(false); - EXPECT_FALSE(callbacks_->animations_started()); - EXPECT_FALSE(callbacks_->animations_ended()); + bool is_destroyed = false; + + TestCallbackLayerAnimationObserver* observer = + new TestCallbackLayerAnimationObserver( + base::Bind(&TestCallbacks::AnimationsStarted, + base::Unretained(&callbacks)), + false, &is_destroyed); + observer->SetActive(); + + EXPECT_FALSE(is_destroyed); + delete observer; +} + +TEST(CallbackLayerAnimationObserverDestructionTest, VerifyTrueAutoDelete) { + TestCallbacks callbacks; + callbacks.set_should_delete_observer_on_animations_ended(false); + + bool is_destroyed = false; + + TestCallbackLayerAnimationObserver* observer = + new TestCallbackLayerAnimationObserver( + base::Bind(&TestCallbacks::AnimationsStarted, + base::Unretained(&callbacks)), + true, &is_destroyed); + observer->SetActive(); + + EXPECT_TRUE(is_destroyed); } TEST(CallbackLayerAnimationObserverDestructionTest, @@ -271,6 +327,15 @@ EXPECT_TRUE(is_destroyed); } +TEST_F(CallbackLayerAnimationObserverTest, VerifyInitialState) { + EXPECT_FALSE(observer_->active()); + EXPECT_EQ(0, observer_->aborted_count()); + EXPECT_EQ(0, observer_->successful_count()); + + EXPECT_FALSE(callbacks_->animations_started()); + EXPECT_FALSE(callbacks_->animations_ended()); +} + // Verifies that the CallbackLayerAnimationObserver is robust to explicit // deletes caused as a side effect of calling the AnimationsStartedCallback() // when there are no animation sequences attached. This test also guards against
diff --git a/ui/compositor/compositor.cc b/ui/compositor/compositor.cc index e648c8a..cab5d6e 100644 --- a/ui/compositor/compositor.cc +++ b/ui/compositor/compositor.cc
@@ -109,7 +109,7 @@ } } settings.renderer_settings.partial_swap_enabled = - !command_line->HasSwitch(cc::switches::kUIDisablePartialSwap); + !command_line->HasSwitch(switches::kUIDisablePartialSwap); #if defined(OS_WIN) settings.renderer_settings.finish_rendering_on_resize = true; #endif
diff --git a/ui/compositor/compositor_switches.cc b/ui/compositor/compositor_switches.cc index 8a5fb98c..113cd5e 100644 --- a/ui/compositor/compositor_switches.cc +++ b/ui/compositor/compositor_switches.cc
@@ -15,6 +15,9 @@ // Forces tests to produce pixel output when they normally wouldn't. const char kEnablePixelOutputInTests[] = "enable-pixel-output-in-tests"; +// Disable partial swap which is needed for some OpenGL drivers / emulators. +const char kUIDisablePartialSwap[] = "ui-disable-partial-swap"; + const char kUIEnableCompositorAnimationTimelines[] = "ui-enable-compositor-animation-timelines";
diff --git a/ui/compositor/compositor_switches.h b/ui/compositor/compositor_switches.h index 683f055..d2fd68c5 100644 --- a/ui/compositor/compositor_switches.h +++ b/ui/compositor/compositor_switches.h
@@ -11,6 +11,7 @@ COMPOSITOR_EXPORT extern const char kEnableHardwareOverlays[]; COMPOSITOR_EXPORT extern const char kEnablePixelOutputInTests[]; +COMPOSITOR_EXPORT extern const char kUIDisablePartialSwap[]; COMPOSITOR_EXPORT extern const char kUIEnableCompositorAnimationTimelines[]; COMPOSITOR_EXPORT extern const char kUIEnableRGBA4444Textures[]; COMPOSITOR_EXPORT extern const char kUIEnableZeroCopy[];
diff --git a/ui/compositor/layer.cc b/ui/compositor/layer.cc index 352a9ce..f370774 100644 --- a/ui/compositor/layer.cc +++ b/ui/compositor/layer.cc
@@ -750,14 +750,6 @@ cc_layer_->RequestCopyOfOutput(request.Pass()); } -void Layer::PaintContents( - SkCanvas* sk_canvas, - const gfx::Rect& clip, - ContentLayerClient::PaintingControlSetting painting_control) { - // The old non-slimming paint path is not used in ui::Compositor. - NOTREACHED(); -} - scoped_refptr<cc::DisplayItemList> Layer::PaintContentsToDisplayList( const gfx::Rect& clip, ContentLayerClient::PaintingControlSetting painting_control) {
diff --git a/ui/compositor/layer.h b/ui/compositor/layer.h index 442d55db3..187a3d9f 100644 --- a/ui/compositor/layer.h +++ b/ui/compositor/layer.h
@@ -348,10 +348,6 @@ void RequestCopyOfOutput(scoped_ptr<cc::CopyOutputRequest> request); // ContentLayerClient - void PaintContents( - SkCanvas* canvas, - const gfx::Rect& clip, - ContentLayerClient::PaintingControlSetting painting_control) override; scoped_refptr<cc::DisplayItemList> PaintContentsToDisplayList( const gfx::Rect& clip, ContentLayerClient::PaintingControlSetting painting_control) override;
diff --git a/ui/mojo/init/screen_mojo.cc b/ui/mojo/init/screen_mojo.cc index 1ed0d41..2590b6a1 100644 --- a/ui/mojo/init/screen_mojo.cc +++ b/ui/mojo/init/screen_mojo.cc
@@ -7,17 +7,13 @@ namespace ui { namespace mojo { -ScreenMojo::ScreenMojo(const gfx::Size& screen_size_in_pixels, - float device_pixel_ratio) - : screen_size_in_pixels_(screen_size_in_pixels), - device_pixel_ratio_(device_pixel_ratio) { - static int64 synthesized_display_id = 2000; - display_.set_id(synthesized_display_id++); - display_.SetScaleAndBounds(device_pixel_ratio, - gfx::Rect(screen_size_in_pixels)); -} +ScreenMojo::ScreenMojo(const std::vector<gfx::Display>& displays) + : displays_(displays) {} + +ScreenMojo::~ScreenMojo() {} gfx::Point ScreenMojo::GetCursorScreenPoint() { + NOTIMPLEMENTED(); return gfx::Point(); } @@ -32,7 +28,7 @@ } gfx::Display ScreenMojo::GetPrimaryDisplay() const { - return display_; + return displays_[0]; } gfx::Display ScreenMojo::GetDisplayNearestWindow(gfx::NativeView view) const { @@ -44,15 +40,29 @@ } int ScreenMojo::GetNumDisplays() const { - return 1; + return static_cast<int>(displays_.size()); } std::vector<gfx::Display> ScreenMojo::GetAllDisplays() const { - return std::vector<gfx::Display>(1, GetPrimaryDisplay()); + return displays_; } gfx::Display ScreenMojo::GetDisplayMatching(const gfx::Rect& match_rect) const { - return GetPrimaryDisplay(); + int biggest_area = 0; + gfx::Display result; + const gfx::Display matching_display; + for (const gfx::Display& display : displays_) { + gfx::Rect display_union(match_rect); + display_union.Union(display.bounds()); + if (!display_union.IsEmpty()) { + const int area = display_union.width() * display_union.height(); + if (area > biggest_area) { + biggest_area = area; + result = display; + } + } + } + return biggest_area == 0 ? displays_[0] : result; } void ScreenMojo::AddObserver(gfx::DisplayObserver* observer) {
diff --git a/ui/mojo/init/screen_mojo.h b/ui/mojo/init/screen_mojo.h index db7f48f..3a3df06 100644 --- a/ui/mojo/init/screen_mojo.h +++ b/ui/mojo/init/screen_mojo.h
@@ -5,8 +5,9 @@ #ifndef UI_MOJO_INIT_SCREEN_MOJO_H_ #define UI_MOJO_INIT_SCREEN_MOJO_H_ +#include <vector> + #include "ui/gfx/display.h" -#include "ui/gfx/geometry/size.h" #include "ui/gfx/screen.h" namespace ui { @@ -14,7 +15,8 @@ class ScreenMojo : public gfx::Screen { public: - ScreenMojo(const gfx::Size& screen_size_in_pixels, float device_pixel_ratio); + explicit ScreenMojo(const std::vector<gfx::Display>& displays); + ~ScreenMojo() override; // gfx::Screen: gfx::Point GetCursorScreenPoint() override; @@ -30,10 +32,7 @@ void RemoveObserver(gfx::DisplayObserver* observer) override; private: - const gfx::Size screen_size_in_pixels_; - const float device_pixel_ratio_; - - gfx::Display display_; + const std::vector<gfx::Display> displays_; DISALLOW_COPY_AND_ASSIGN(ScreenMojo); };
diff --git a/ui/mojo/init/ui_init.cc b/ui/mojo/init/ui_init.cc index 937112ee..3b4c4ab 100644 --- a/ui/mojo/init/ui_init.cc +++ b/ui/mojo/init/ui_init.cc
@@ -39,8 +39,8 @@ }; #endif -UIInit::UIInit(const gfx::Size& screen_size_in_pixels, float device_pixel_ratio) - : screen_(new ScreenMojo(screen_size_in_pixels, device_pixel_ratio)) { +UIInit::UIInit(const std::vector<gfx::Display>& displays) + : screen_(new ScreenMojo(displays)) { gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, screen_.get()); #if defined(OS_ANDROID) gesture_configuration_.reset(new GestureConfigurationMojo);
diff --git a/ui/mojo/init/ui_init.h b/ui/mojo/init/ui_init.h index eeaebc6..48ca7db 100644 --- a/ui/mojo/init/ui_init.h +++ b/ui/mojo/init/ui_init.h
@@ -5,13 +5,15 @@ #ifndef UI_MOJO_INIT_UI_INIT_H_ #define UI_MOJO_INIT_UI_INIT_H_ +#include <vector> + #include "base/basictypes.h" #include "base/callback_forward.h" #include "base/memory/scoped_ptr.h" namespace gfx { +class Display; class Screen; -class Size; } namespace ui { @@ -25,7 +27,7 @@ // including aura). class UIInit { public: - UIInit(const gfx::Size& screen_size_in_pixels, float device_pixel_ratio); + explicit UIInit(const std::vector<gfx::Display>& displays); ~UIInit(); private:
diff --git a/ui/snapshot/BUILD.gn b/ui/snapshot/BUILD.gn index a9e5b0b..c79a70b3 100644 --- a/ui/snapshot/BUILD.gn +++ b/ui/snapshot/BUILD.gn
@@ -30,7 +30,7 @@ "//ui/gfx/geometry", ] - if (is_android) { + if (is_android && !use_aura) { deps += [ "//ui/android" ] } @@ -46,6 +46,10 @@ ] } + if (is_android && use_aura) { + sources -= [ "snapshot_android.cc" ] + } + if (use_aura) { deps += [ "//ui/aura",
diff --git a/ui/views/controls/menu/menu_controller.cc b/ui/views/controls/menu/menu_controller.cc index b3a6ada..0391d54 100644 --- a/ui/views/controls/menu/menu_controller.cc +++ b/ui/views/controls/menu/menu_controller.cc
@@ -482,65 +482,23 @@ } } -bool MenuController::OnMousePressed(SubmenuView* source, +void MenuController::OnMousePressed(SubmenuView* source, const ui::MouseEvent& event) { - // We should either have no current_mouse_event_target_, or should have a - // pressed state stored. - DCHECK(!current_mouse_event_target_ || current_mouse_pressed_state_); - - // Find the root view to check. If any buttons were previously pressed, this - // is the same root view we've been forwarding to. Otherwise, it's the root - // view of the target. - MenuHostRootView* forward_to_root = - current_mouse_pressed_state_ ? current_mouse_event_target_ - : GetRootView(source, event.location()); - - current_mouse_pressed_state_ |= event.changed_button_flags(); - - if (forward_to_root) { - ui::MouseEvent event_for_root(event); - ConvertLocatedEventForRootView(source, forward_to_root, &event_for_root); - View* view = - forward_to_root->GetEventHandlerForPoint(event_for_root.location()); - // Empty menu items are always handled by the menu controller. - if (!view || view->id() != MenuItemView::kEmptyMenuItemViewID) { - bool processed = forward_to_root->ProcessMousePressed(event_for_root); - // If the event was processed, the root view becomes our current mouse - // handler... - if (processed && !current_mouse_event_target_) { - current_mouse_event_target_ = forward_to_root; - } - - // ...and we always return the result of the current handler. - if (current_mouse_event_target_) - return processed; - } - } - - // Otherwise, the menu handles this click directly. SetSelectionOnPointerDown(source, event); - return true; } -bool MenuController::OnMouseDragged(SubmenuView* source, +void MenuController::OnMouseDragged(SubmenuView* source, const ui::MouseEvent& event) { - if (current_mouse_event_target_) { - ui::MouseEvent event_for_root(event); - ConvertLocatedEventForRootView(source, current_mouse_event_target_, - &event_for_root); - return current_mouse_event_target_->ProcessMouseDragged(event_for_root); - } - MenuPart part = GetMenuPart(source, event.location()); UpdateScrolling(part); if (!blocking_run_) - return false; + return; if (possible_drag_) { if (View::ExceededDragThreshold(event.location() - press_pt_)) StartDrag(source, press_pt_); - return true; + return; } MenuItemView* mouse_menu = NULL; if (part.type == MenuPart::MENU_ITEM) { @@ -553,29 +511,10 @@ ShowSiblingMenu(source, event.location()); } UpdateActiveMouseView(source, event, mouse_menu); - - return true; } void MenuController::OnMouseReleased(SubmenuView* source, const ui::MouseEvent& event) { - current_mouse_pressed_state_ &= ~event.changed_button_flags(); - - if (current_mouse_event_target_) { - // If this was the final mouse button, then remove the forwarding target. - // We need to do this *before* dispatching the event to the root view - // because there's a chance that the event will open a nested (and blocking) - // menu, and we need to not have a forwarded root view. - MenuHostRootView* cached_event_target = current_mouse_event_target_; - if (!current_mouse_pressed_state_) - current_mouse_event_target_ = nullptr; - ui::MouseEvent event_for_root(event); - ConvertLocatedEventForRootView(source, cached_event_target, - &event_for_root); - cached_event_target->ProcessMouseReleased(event_for_root); - return; - } - if (!blocking_run_) return; @@ -650,17 +589,6 @@ void MenuController::OnMouseMoved(SubmenuView* source, const ui::MouseEvent& event) { - if (current_mouse_event_target_) { - ui::MouseEvent event_for_root(event); - ConvertLocatedEventForRootView(source, current_mouse_event_target_, - &event_for_root); - current_mouse_event_target_->ProcessMouseMoved(event_for_root); - return; - } - - MenuHostRootView* root_view = GetRootView(source, event.location()); - if (root_view) - root_view->ProcessMouseMoved(event); HandleMouseLocation(source, event.location()); } @@ -724,23 +652,6 @@ part.submenu->OnGestureEvent(event); } -View* MenuController::GetTooltipHandlerForPoint(SubmenuView* source, - const gfx::Point& point) { - MenuHostRootView* root_view = GetRootView(source, point); - return root_view ? root_view->ProcessGetTooltipHandlerForPoint(point) - : nullptr; -} - -void MenuController::ViewHierarchyChanged( - SubmenuView* source, - const View::ViewHierarchyChangedDetails& details) { - // If the current mouse handler is removed, remove it as the handler. - if (!details.is_add && details.child == current_mouse_event_target_) { - current_mouse_event_target_ = nullptr; - current_mouse_pressed_state_ = 0; - } -} - bool MenuController::GetDropFormats( SubmenuView* source, int* formats, @@ -894,11 +805,6 @@ void MenuController::OnDragComplete(bool should_close) { DCHECK(drag_in_progress_); drag_in_progress_ = false; - // During a drag, mouse events are processed directly by the widget, and not - // sent to the MenuController. At drag completion, reset pressed state and - // the event target. - current_mouse_pressed_state_ = 0; - current_mouse_event_target_ = nullptr; if (showing_ && should_close && GetActiveInstance() == this) { CloseAllNestedMenus(); Cancel(EXIT_ALL); @@ -1243,8 +1149,6 @@ menu_start_time_(base::TimeTicks()), is_combobox_(false), item_selected_by_touch_(false), - current_mouse_event_target_(nullptr), - current_mouse_pressed_state_(0), message_loop_(MenuMessageLoop::Create()) { active_instance_ = this; } @@ -1524,26 +1428,6 @@ return true; } -MenuHostRootView* MenuController::GetRootView(SubmenuView* submenu, - const gfx::Point& source_loc) { - MenuPart part = GetMenuPart(submenu, source_loc); - SubmenuView* view = part.submenu; - return view && view->GetWidget() - ? static_cast<MenuHostRootView*>(view->GetWidget()->GetRootView()) - : nullptr; -} - -void MenuController::ConvertLocatedEventForRootView(View* source, - View* dst, - ui::LocatedEvent* event) { - if (source->GetWidget()->GetRootView() == dst) - return; - gfx::Point new_location(event->location()); - View::ConvertPointToScreen(source, &new_location); - View::ConvertPointFromScreen(dst, &new_location); - event->set_location(new_location); -} - bool MenuController::DoesSubmenuContainLocation(SubmenuView* submenu, const gfx::Point& screen_loc) { gfx::Point view_loc = screen_loc;
diff --git a/ui/views/controls/menu/menu_controller.h b/ui/views/controls/menu/menu_controller.h index 0b5344d..1fa1e90 100644 --- a/ui/views/controls/menu/menu_controller.h +++ b/ui/views/controls/menu/menu_controller.h
@@ -132,16 +132,13 @@ // // NOTE: the coordinates of the events are in that of the // MenuScrollViewContainer. - bool OnMousePressed(SubmenuView* source, const ui::MouseEvent& event); - bool OnMouseDragged(SubmenuView* source, const ui::MouseEvent& event); + void OnMousePressed(SubmenuView* source, const ui::MouseEvent& event); + void OnMouseDragged(SubmenuView* source, const ui::MouseEvent& event); void OnMouseReleased(SubmenuView* source, const ui::MouseEvent& event); void OnMouseMoved(SubmenuView* source, const ui::MouseEvent& event); void OnMouseEntered(SubmenuView* source, const ui::MouseEvent& event); bool OnMouseWheel(SubmenuView* source, const ui::MouseWheelEvent& event); void OnGestureEvent(SubmenuView* source, ui::GestureEvent* event); - View* GetTooltipHandlerForPoint(SubmenuView* source, const gfx::Point& point); - void ViewHierarchyChanged(SubmenuView* source, - const View::ViewHierarchyChangedDetails& details); bool GetDropFormats(SubmenuView* source, int* formats, @@ -372,17 +369,6 @@ const gfx::Point& screen_loc, MenuPart* part); - // Returns the RootView of the target for the mouse event, if there is a - // target at |source_loc|. - MenuHostRootView* GetRootView(SubmenuView* source, - const gfx::Point& source_loc); - - // Converts the located event from |source|'s geometry to |dst|'s geometry, - // iff the root view of source and dst differ. - void ConvertLocatedEventForRootView(View* source, - View* dst, - ui::LocatedEvent* event); - // Returns true if the SubmenuView contains the specified location. This does // NOT included the scroll buttons, only the submenu view. bool DoesSubmenuContainLocation(SubmenuView* submenu, @@ -655,15 +641,6 @@ // Set to true if the menu item was selected by touch. bool item_selected_by_touch_; - // During mouse event handling, this is the RootView to forward mouse events - // to. We need this, because if we forward one event to it (e.g., mouse - // pressed), subsequent events (like dragging) should also go to it, even if - // the mouse is no longer over the view. - MenuHostRootView* current_mouse_event_target_; - - // A mask of the EventFlags for the mouse buttons currently pressed. - int current_mouse_pressed_state_; - scoped_ptr<MenuMessageLoop> message_loop_; DISALLOW_COPY_AND_ASSIGN(MenuController);
diff --git a/ui/views/controls/menu/menu_host_root_view.cc b/ui/views/controls/menu/menu_host_root_view.cc index 362971f..1bc834a0 100644 --- a/ui/views/controls/menu/menu_host_root_view.cc +++ b/ui/views/controls/menu/menu_host_root_view.cc
@@ -10,25 +10,42 @@ namespace views { -MenuHostRootView::MenuHostRootView(Widget* widget, SubmenuView* submenu) - : internal::RootView(widget), submenu_(submenu) {} +MenuHostRootView::MenuHostRootView(Widget* widget, + SubmenuView* submenu) + : internal::RootView(widget), + submenu_(submenu), + forward_drag_to_menu_controller_(true) { +} bool MenuHostRootView::OnMousePressed(const ui::MouseEvent& event) { - return GetMenuController() && - GetMenuController()->OnMousePressed(submenu_, event); + forward_drag_to_menu_controller_ = + !GetLocalBounds().Contains(event.location()) || + !RootView::OnMousePressed(event) || + DoesEventTargetEmptyMenuItem(event); + + if (forward_drag_to_menu_controller_ && GetMenuController()) + GetMenuController()->OnMousePressed(submenu_, event); + return true; } bool MenuHostRootView::OnMouseDragged(const ui::MouseEvent& event) { - return GetMenuController() && - GetMenuController()->OnMouseDragged(submenu_, event); + if (forward_drag_to_menu_controller_ && GetMenuController()) { + GetMenuController()->OnMouseDragged(submenu_, event); + return true; + } + return RootView::OnMouseDragged(event); } void MenuHostRootView::OnMouseReleased(const ui::MouseEvent& event) { - if (GetMenuController()) + RootView::OnMouseReleased(event); + if (forward_drag_to_menu_controller_ && GetMenuController()) { + forward_drag_to_menu_controller_ = false; GetMenuController()->OnMouseReleased(submenu_, event); + } } void MenuHostRootView::OnMouseMoved(const ui::MouseEvent& event) { + RootView::OnMouseMoved(event); if (GetMenuController()) GetMenuController()->OnMouseMoved(submenu_, event); } @@ -38,40 +55,6 @@ GetMenuController()->OnMouseWheel(submenu_, event); } -View* MenuHostRootView::GetTooltipHandlerForPoint(const gfx::Point& point) { - return GetMenuController() - ? GetMenuController()->GetTooltipHandlerForPoint(submenu_, point) - : nullptr; -} - -void MenuHostRootView::ViewHierarchyChanged( - const ViewHierarchyChangedDetails& details) { - if (GetMenuController()) - GetMenuController()->ViewHierarchyChanged(submenu_, details); - RootView::ViewHierarchyChanged(details); -} - -bool MenuHostRootView::ProcessMousePressed(const ui::MouseEvent& event) { - return RootView::OnMousePressed(event); -} - -bool MenuHostRootView::ProcessMouseDragged(const ui::MouseEvent& event) { - return RootView::OnMouseDragged(event); -} - -void MenuHostRootView::ProcessMouseReleased(const ui::MouseEvent& event) { - RootView::OnMouseReleased(event); -} - -void MenuHostRootView::ProcessMouseMoved(const ui::MouseEvent& event) { - RootView::OnMouseMoved(event); -} - -View* MenuHostRootView::ProcessGetTooltipHandlerForPoint( - const gfx::Point& point) { - return RootView::GetTooltipHandlerForPoint(point); -} - void MenuHostRootView::OnEventProcessingFinished(ui::Event* event) { RootView::OnEventProcessingFinished(event); @@ -87,4 +70,10 @@ return submenu_ ? submenu_->GetMenuItem()->GetMenuController() : NULL; } +bool MenuHostRootView::DoesEventTargetEmptyMenuItem( + const ui::MouseEvent& event) { + View* view = GetEventHandlerForPoint(event.location()); + return view && view->id() == MenuItemView::kEmptyMenuItemViewID; +} + } // namespace views
diff --git a/ui/views/controls/menu/menu_host_root_view.h b/ui/views/controls/menu/menu_host_root_view.h index 1a2aabd..cdb6b40 100644 --- a/ui/views/controls/menu/menu_host_root_view.h +++ b/ui/views/controls/menu/menu_host_root_view.h
@@ -30,15 +30,6 @@ void OnMouseReleased(const ui::MouseEvent& event) override; void OnMouseMoved(const ui::MouseEvent& event) override; bool OnMouseWheel(const ui::MouseWheelEvent& event) override; - View* GetTooltipHandlerForPoint(const gfx::Point& point) override; - void ViewHierarchyChanged(const ViewHierarchyChangedDetails& details) - override; - - bool ProcessMousePressed(const ui::MouseEvent& event); - bool ProcessMouseDragged(const ui::MouseEvent& event); - void ProcessMouseReleased(const ui::MouseEvent& event); - void ProcessMouseMoved(const ui::MouseEvent& event); - View* ProcessGetTooltipHandlerForPoint(const gfx::Point& point); private: // ui::EventProcessor: @@ -47,9 +38,15 @@ // Returns the MenuController for this MenuHostRootView. MenuController* GetMenuController(); + // Returns true if event targets EmptyMenu. + bool DoesEventTargetEmptyMenuItem(const ui::MouseEvent& event); + // The SubmenuView we contain. SubmenuView* submenu_; + // Whether mouse dragged/released should be forwarded to the MenuController. + bool forward_drag_to_menu_controller_; + DISALLOW_COPY_AND_ASSIGN(MenuHostRootView); };
diff --git a/ui/views/mus/aura_init.cc b/ui/views/mus/aura_init.cc index 47aabe5..ddbab0d 100644 --- a/ui/views/mus/aura_init.cc +++ b/ui/views/mus/aura_init.cc
@@ -7,13 +7,15 @@ #include "base/i18n/icu_util.h" #include "base/lazy_instance.h" #include "base/path_service.h" -#include "components/mus/public/cpp/view.h" +#include "components/mus/public/cpp/window.h" #include "components/resource_provider/public/cpp/resource_loader.h" +#include "mojo/application/public/cpp/application_impl.h" #include "mojo/converters/geometry/geometry_type_converters.h" #include "ui/aura/env.h" #include "ui/base/ime/input_method_initializer.h" #include "ui/base/resource/resource_bundle.h" #include "ui/base/ui_base_paths.h" +#include "ui/gfx/display.h" #if defined(OS_LINUX) && !defined(OS_ANDROID) #include "components/font_service/public/cpp/font_loader.h" @@ -29,19 +31,32 @@ return paths; } +std::vector<gfx::Display> GetDisplaysFromWindow(mus::Window* window) { + static int64 synthesized_display_id = 2000; + gfx::Display display; + display.set_id(synthesized_display_id++); + display.SetScaleAndBounds( + window->viewport_metrics().device_pixel_ratio, + gfx::Rect(window->viewport_metrics().size_in_pixels.To<gfx::Size>())); + std::vector<gfx::Display> displays; + displays.push_back(display); + return displays; +} + } // namespace -// TODO(sky): the 1.f should be view->viewport_metrics().device_scale_factor, -// but that causes clipping problems. No doubt we're not scaling a size -// correctly. -AuraInit::AuraInit(mus::View* view, - mojo::Shell* shell, - const std::string& resource_file) - : ui_init_(view->viewport_metrics().size_in_pixels.To<gfx::Size>(), 1.f), - resource_file_(resource_file) { +AuraInit::AuraInit(mojo::ApplicationImpl* app, + const std::string& resource_file, + mus::Window* window) + : AuraInit(app, resource_file, GetDisplaysFromWindow(window)) {} + +AuraInit::AuraInit(mojo::ApplicationImpl* app, + const std::string& resource_file, + const std::vector<gfx::Display>& displays) + : ui_init_(displays), resource_file_(resource_file) { aura::Env::CreateInstance(false); - InitializeResources(shell); + InitializeResources(app); ui::InitializeInputMethodForTesting(); } @@ -58,11 +73,11 @@ #endif } -void AuraInit::InitializeResources(mojo::Shell* shell) { +void AuraInit::InitializeResources(mojo::ApplicationImpl* app) { if (ui::ResourceBundle::HasSharedInstance()) return; resource_provider::ResourceLoader resource_loader( - shell, GetResourcePaths(resource_file_)); + app, GetResourcePaths(resource_file_)); if (!resource_loader.BlockUntilLoaded()) return; CHECK(resource_loader.loaded()); @@ -79,7 +94,7 @@ // Initialize the skia font code to go ask fontconfig underneath. #if defined(OS_LINUX) && !defined(OS_ANDROID) - font_loader_ = skia::AdoptRef(new font_service::FontLoader(shell)); + font_loader_ = skia::AdoptRef(new font_service::FontLoader(app->shell())); SkFontConfigInterface::SetGlobal(font_loader_.get()); #endif
diff --git a/ui/views/mus/aura_init.h b/ui/views/mus/aura_init.h index 319a9c33..daa1b3c 100644 --- a/ui/views/mus/aura_init.h +++ b/ui/views/mus/aura_init.h
@@ -6,6 +6,7 @@ #define UI_VIEWS_MUS_AURA_INIT_H_ #include <string> +#include <vector> #include "skia/ext/refptr.h" #include "ui/mojo/init/ui_init.h" @@ -14,12 +15,16 @@ class FontLoader; } +namespace gfx { +class Display; +} + namespace mojo { -class Shell; +class ApplicationImpl; } namespace mus { -class View; +class Window; } namespace views { @@ -28,13 +33,18 @@ // |resource_file| is the path to the apk file containing the resources. class AuraInit { public: - AuraInit(mus::View* root, - mojo::Shell* shell, - const std::string& resource_file); + // This constructor builds the set of Displays from the ViewportMetrics of + // |window|. + AuraInit(mojo::ApplicationImpl* app, + const std::string& resource_file, + mus::Window* window); + AuraInit(mojo::ApplicationImpl* app, + const std::string& resource_file, + const std::vector<gfx::Display>& displays); ~AuraInit(); private: - void InitializeResources(mojo::Shell* shell); + void InitializeResources(mojo::ApplicationImpl* app); ui::mojo::UIInit ui_init_;
diff --git a/ui/views/mus/input_method_mus.cc b/ui/views/mus/input_method_mus.cc index a7222dd..cea183cb 100644 --- a/ui/views/mus/input_method_mus.cc +++ b/ui/views/mus/input_method_mus.cc
@@ -4,7 +4,7 @@ #include "ui/views/mus/input_method_mus.h" -#include "components/mus/public/cpp/view.h" +#include "components/mus/public/cpp/window.h" #include "mojo/converters/ime/ime_type_converters.h" #include "ui/base/ime/text_input_client.h" #include "ui/events/event.h" @@ -16,8 +16,8 @@ // InputMethodMUS, public: InputMethodMUS::InputMethodMUS(ui::internal::InputMethodDelegate* delegate, - mus::View* view) - : view_(view) { + mus::Window* window) + : window_(window) { SetDelegate(delegate); } @@ -96,9 +96,9 @@ mojo::TextInputStatePtr state = mojo::TextInputState::New(); state->type = mojo::ConvertTo<mojo::TextInputType>(type); if (type != ui::TEXT_INPUT_TYPE_NONE) - view_->SetImeVisibility(true, state.Pass()); + window_->SetImeVisibility(true, state.Pass()); else - view_->SetTextInputState(state.Pass()); + window_->SetTextInputState(state.Pass()); } } // namespace mandoline
diff --git a/ui/views/mus/input_method_mus.h b/ui/views/mus/input_method_mus.h index da17efa..a9be768 100644 --- a/ui/views/mus/input_method_mus.h +++ b/ui/views/mus/input_method_mus.h
@@ -8,14 +8,15 @@ #define UI_VIEWS_MUS_INPUT_METHOD_MUS_H_ namespace mus { -class View; +class Window; } // namespace mojo namespace views { class InputMethodMUS : public ui::InputMethodBase { public: - InputMethodMUS(ui::internal::InputMethodDelegate* delegate, mus::View* view); + InputMethodMUS(ui::internal::InputMethodDelegate* delegate, + mus::Window* window); ~InputMethodMUS() override; private: @@ -38,8 +39,8 @@ void UpdateTextInputType(); - // The toplevel view which is not owned by this class. - mus::View* view_; + // The toplevel window which is not owned by this class. + mus::Window* window_; DISALLOW_COPY_AND_ASSIGN(InputMethodMUS); };
diff --git a/ui/views/mus/native_widget_view_manager.cc b/ui/views/mus/native_widget_view_manager.cc index 43bdb2d4..a08080d 100644 --- a/ui/views/mus/native_widget_view_manager.cc +++ b/ui/views/mus/native_widget_view_manager.cc
@@ -4,7 +4,7 @@ #include "ui/views/mus/native_widget_view_manager.h" -#include "components/mus/public/cpp/view.h" +#include "components/mus/public/cpp/window.h" #include "mojo/converters/geometry/geometry_type_converters.h" #include "mojo/converters/input_events/input_events_type_converters.h" #include "ui/aura/client/default_capture_client.h" @@ -34,44 +34,45 @@ DISALLOW_COPY_AND_ASSIGN(FocusRulesImpl); }; -class NativeWidgetViewObserver : public mus::ViewObserver { +class NativeWidgetWindowObserver : public mus::WindowObserver { public: - NativeWidgetViewObserver(NativeWidgetViewManager* view_manager) + NativeWidgetWindowObserver(NativeWidgetViewManager* view_manager) : view_manager_(view_manager) { - view_manager_->view_->AddObserver(this); + view_manager_->window_->AddObserver(this); } - ~NativeWidgetViewObserver() override { - if (view_manager_->view_) - view_manager_->view_->RemoveObserver(this); + ~NativeWidgetWindowObserver() override { + if (view_manager_->window_) + view_manager_->window_->RemoveObserver(this); } private: - // ViewObserver: - void OnViewDestroyed(mus::View* view) override { - DCHECK_EQ(view, view_manager_->view_); + // WindowObserver: + void OnWindowDestroyed(mus::Window* view) override { + DCHECK_EQ(view, view_manager_->window_); view->RemoveObserver(this); - view_manager_->view_ = nullptr; + view_manager_->window_ = nullptr; // TODO(sky): WindowTreeHostMojo assumes the View outlives it. - // NativeWidgetViewObserver needs to deal, likely by deleting this. + // NativeWidgetWindowObserver needs to deal, likely by deleting this. } - void OnViewBoundsChanged(mus::View* view, - const mojo::Rect& old_bounds, - const mojo::Rect& new_bounds) override { + void OnWindowBoundsChanged(mus::Window* view, + const mojo::Rect& old_bounds, + const mojo::Rect& new_bounds) override { gfx::Rect view_rect = view->bounds().To<gfx::Rect>(); view_manager_->SetBounds(gfx::Rect(view_rect.size())); } - void OnViewFocusChanged(mus::View* gained_focus, - mus::View* lost_focus) override { - if (gained_focus == view_manager_->view_) + void OnWindowFocusChanged(mus::Window* gained_focus, + mus::Window* lost_focus) override { + if (gained_focus == view_manager_->window_) view_manager_->window_tree_host_->GetInputMethod()->OnFocus(); - else if (lost_focus == view_manager_->view_) + else if (lost_focus == view_manager_->window_) view_manager_->window_tree_host_->GetInputMethod()->OnBlur(); } - void OnViewInputEvent(mus::View* view, const mojo::EventPtr& event) override { + void OnWindowInputEvent(mus::Window* view, + const mojo::EventPtr& event) override { scoped_ptr<ui::Event> ui_event(event.To<scoped_ptr<ui::Event>>()); if (!ui_event) return; @@ -86,7 +87,7 @@ NativeWidgetViewManager* const view_manager_; - DISALLOW_COPY_AND_ASSIGN(NativeWidgetViewObserver); + DISALLOW_COPY_AND_ASSIGN(NativeWidgetWindowObserver); }; } // namespace @@ -94,9 +95,9 @@ NativeWidgetViewManager::NativeWidgetViewManager( views::internal::NativeWidgetDelegate* delegate, mojo::Shell* shell, - mus::View* view) - : NativeWidgetAura(delegate), view_(view) { - window_tree_host_.reset(new WindowTreeHostMojo(shell, view_)); + mus::Window* window) + : NativeWidgetAura(delegate), window_(window) { + window_tree_host_.reset(new WindowTreeHostMojo(shell, window_)); window_tree_host_->InitHost(); focus_client_.reset(new wm::FocusController(new FocusRulesImpl)); @@ -110,7 +111,7 @@ capture_client_.reset( new aura::client::DefaultCaptureClient(window_tree_host_->window())); - view_observer_.reset(new NativeWidgetViewObserver(this)); + window_observer_.reset(new NativeWidgetWindowObserver(this)); } NativeWidgetViewManager::~NativeWidgetViewManager() {} @@ -124,7 +125,7 @@ void NativeWidgetViewManager::OnWindowVisibilityChanged(aura::Window* window, bool visible) { - view_->SetVisible(visible); + window_->SetVisible(visible); // NOTE: We could also update aura::Window's visibility when the View's // visibility changes, but this code isn't going to be around for very long so // I'm not bothering.
diff --git a/ui/views/mus/native_widget_view_manager.h b/ui/views/mus/native_widget_view_manager.h index 0c9df020..9c3247e 100644 --- a/ui/views/mus/native_widget_view_manager.h +++ b/ui/views/mus/native_widget_view_manager.h
@@ -18,7 +18,7 @@ } namespace mus { -class View; +class Window; } namespace ui { @@ -34,7 +34,7 @@ namespace views { namespace { -class NativeWidgetViewObserver; +class NativeWidgetWindowObserver; } class WindowTreeHostMojo; @@ -43,22 +43,22 @@ public: NativeWidgetViewManager(views::internal::NativeWidgetDelegate* delegate, mojo::Shell* shell, - mus::View* view); + mus::Window* window); ~NativeWidgetViewManager() override; private: - friend class NativeWidgetViewObserver; + friend class NativeWidgetWindowObserver; // Overridden from internal::NativeWidgetAura: void InitNativeWidget(const views::Widget::InitParams& in_params) override; void OnWindowVisibilityChanged(aura::Window* window, bool visible) override; scoped_ptr<WindowTreeHostMojo> window_tree_host_; - scoped_ptr<NativeWidgetViewObserver> view_observer_; + scoped_ptr<NativeWidgetWindowObserver> window_observer_; scoped_ptr<wm::FocusController> focus_client_; - mus::View* view_; + mus::Window* window_; scoped_ptr<aura::client::DefaultCaptureClient> capture_client_;
diff --git a/ui/views/mus/surface_binding.cc b/ui/views/mus/surface_binding.cc index c622698..168ff50 100644 --- a/ui/views/mus/surface_binding.cc +++ b/ui/views/mus/surface_binding.cc
@@ -16,8 +16,8 @@ #include "cc/resources/shared_bitmap_manager.h" #include "components/mus/public/cpp/context_provider.h" #include "components/mus/public/cpp/output_surface.h" -#include "components/mus/public/cpp/view.h" -#include "components/mus/public/cpp/view_tree_connection.h" +#include "components/mus/public/cpp/window.h" +#include "components/mus/public/cpp/window_tree_connection.h" #include "components/mus/public/interfaces/gpu.mojom.h" #include "mojo/application/public/cpp/connect.h" #include "mojo/application/public/interfaces/shell.mojom.h" @@ -42,26 +42,26 @@ : public base::RefCounted<PerConnectionState> { public: static PerConnectionState* Get(mojo::Shell* shell, - mus::ViewTreeConnection* connection); + mus::WindowTreeConnection* connection); - scoped_ptr<cc::OutputSurface> CreateOutputSurface(mus::View* view); + scoped_ptr<cc::OutputSurface> CreateOutputSurface(mus::Window* window); private: - typedef std::map<mus::ViewTreeConnection*, PerConnectionState*> + typedef std::map<mus::WindowTreeConnection*, PerConnectionState*> ConnectionToStateMap; friend class base::RefCounted<PerConnectionState>; - PerConnectionState(mojo::Shell* shell, mus::ViewTreeConnection* connection); + PerConnectionState(mojo::Shell* shell, mus::WindowTreeConnection* connection); ~PerConnectionState(); void Init(); static base::LazyInstance< - base::ThreadLocalPointer<ConnectionToStateMap>>::Leaky view_states; + base::ThreadLocalPointer<ConnectionToStateMap>>::Leaky window_states; mojo::Shell* shell_; - mus::ViewTreeConnection* connection_; + mus::WindowTreeConnection* connection_; // Set of state needed to create an OutputSurface. mojo::GpuPtr gpu_; @@ -72,26 +72,26 @@ // static base::LazyInstance<base::ThreadLocalPointer< SurfaceBinding::PerConnectionState::ConnectionToStateMap>>::Leaky - SurfaceBinding::PerConnectionState::view_states; + SurfaceBinding::PerConnectionState::window_states; // static SurfaceBinding::PerConnectionState* SurfaceBinding::PerConnectionState::Get( mojo::Shell* shell, - mus::ViewTreeConnection* connection) { - ConnectionToStateMap* view_map = view_states.Pointer()->Get(); - if (!view_map) { - view_map = new ConnectionToStateMap; - view_states.Pointer()->Set(view_map); + mus::WindowTreeConnection* connection) { + ConnectionToStateMap* window_map = window_states.Pointer()->Get(); + if (!window_map) { + window_map = new ConnectionToStateMap; + window_states.Pointer()->Set(window_map); } - if (!(*view_map)[connection]) { - (*view_map)[connection] = new PerConnectionState(shell, connection); - (*view_map)[connection]->Init(); + if (!(*window_map)[connection]) { + (*window_map)[connection] = new PerConnectionState(shell, connection); + (*window_map)[connection]->Init(); } - return (*view_map)[connection]; + return (*window_map)[connection]; } scoped_ptr<cc::OutputSurface> -SurfaceBinding::PerConnectionState::CreateOutputSurface(mus::View* view) { +SurfaceBinding::PerConnectionState::CreateOutputSurface(mus::Window* window) { // TODO(sky): figure out lifetime here. Do I need to worry about the return // value outliving this? mojo::CommandBufferPtr cb; @@ -100,22 +100,22 @@ scoped_refptr<cc::ContextProvider> context_provider( new mus::ContextProvider(cb.PassInterface().PassHandle())); return make_scoped_ptr( - new mus::OutputSurface(context_provider, view->RequestSurface())); + new mus::OutputSurface(context_provider, window->RequestSurface())); } SurfaceBinding::PerConnectionState::PerConnectionState( mojo::Shell* shell, - mus::ViewTreeConnection* connection) + mus::WindowTreeConnection* connection) : shell_(shell), connection_(connection) {} SurfaceBinding::PerConnectionState::~PerConnectionState() { - ConnectionToStateMap* view_map = view_states.Pointer()->Get(); - DCHECK(view_map); - DCHECK_EQ(this, (*view_map)[connection_]); - view_map->erase(connection_); - if (view_map->empty()) { - delete view_map; - view_states.Pointer()->Set(nullptr); + ConnectionToStateMap* window_map = window_states.Pointer()->Get(); + DCHECK(window_map); + DCHECK_EQ(this, (*window_map)[connection_]); + window_map->erase(connection_); + if (window_map->empty()) { + delete window_map; + window_states.Pointer()->Set(nullptr); } } @@ -131,13 +131,14 @@ // SurfaceBinding -------------------------------------------------------------- -SurfaceBinding::SurfaceBinding(mojo::Shell* shell, mus::View* view) - : view_(view), state_(PerConnectionState::Get(shell, view->connection())) {} +SurfaceBinding::SurfaceBinding(mojo::Shell* shell, mus::Window* window) + : window_(window), + state_(PerConnectionState::Get(shell, window->connection())) {} SurfaceBinding::~SurfaceBinding() {} scoped_ptr<cc::OutputSurface> SurfaceBinding::CreateOutputSurface() { - return state_->CreateOutputSurface(view_); + return state_->CreateOutputSurface(window_); } } // namespace views
diff --git a/ui/views/mus/surface_binding.h b/ui/views/mus/surface_binding.h index 9d3984d..3fd0c60 100644 --- a/ui/views/mus/surface_binding.h +++ b/ui/views/mus/surface_binding.h
@@ -17,22 +17,22 @@ } namespace mus { -class View; +class Window; } namespace views { // SurfaceBinding is responsible for managing the connections necessary to -// bind a View to the surfaces service. +// bind a Window to the surfaces service. // Internally SurfaceBinding manages one connection (and related structures) per // ViewTreeConnection. That is, all Views from a particular ViewTreeConnection // share the same connection. class SurfaceBinding { public: - SurfaceBinding(mojo::Shell* shell, mus::View* view); + SurfaceBinding(mojo::Shell* shell, mus::Window* window); ~SurfaceBinding(); - // Creates an OutputSurface that renders to the View supplied to the + // Creates an OutputSurface that renders to the Window supplied to the // constructor. scoped_ptr<cc::OutputSurface> CreateOutputSurface(); @@ -40,7 +40,7 @@ class PerConnectionState; mojo::Shell* shell_; - mus::View* view_; + mus::Window* window_; scoped_refptr<PerConnectionState> state_; DISALLOW_COPY_AND_ASSIGN(SurfaceBinding);
diff --git a/ui/views/mus/surface_context_factory.cc b/ui/views/mus/surface_context_factory.cc index e6c8b52d..4ed3da6 100644 --- a/ui/views/mus/surface_context_factory.cc +++ b/ui/views/mus/surface_context_factory.cc
@@ -7,7 +7,7 @@ #include "cc/output/output_surface.h" #include "cc/resources/shared_bitmap_manager.h" #include "cc/surfaces/surface_id_allocator.h" -#include "components/mus/public/cpp/view.h" +#include "components/mus/public/cpp/window.h" #include "mojo/application/public/interfaces/shell.mojom.h" #include "ui/compositor/reflector.h" #include "ui/gl/gl_bindings.h" @@ -26,8 +26,8 @@ } SurfaceContextFactory::SurfaceContextFactory(mojo::Shell* shell, - mus::View* view) - : surface_binding_(shell, view), next_surface_id_namespace_(1u) {} + mus::Window* window) + : surface_binding_(shell, window), next_surface_id_namespace_(1u) {} SurfaceContextFactory::~SurfaceContextFactory() {}
diff --git a/ui/views/mus/surface_context_factory.h b/ui/views/mus/surface_context_factory.h index 5c34bb5..e20e83ac 100644 --- a/ui/views/mus/surface_context_factory.h +++ b/ui/views/mus/surface_context_factory.h
@@ -15,14 +15,14 @@ } namespace mus { -class View; +class Window; } namespace views { class SurfaceContextFactory : public ui::ContextFactory { public: - SurfaceContextFactory(mojo::Shell* shell, mus::View* view); + SurfaceContextFactory(mojo::Shell* shell, mus::Window* window); ~SurfaceContextFactory() override; private:
diff --git a/ui/views/mus/window_tree_host_mus.cc b/ui/views/mus/window_tree_host_mus.cc index 2d59489c..4e69d0a 100644 --- a/ui/views/mus/window_tree_host_mus.cc +++ b/ui/views/mus/window_tree_host_mus.cc
@@ -4,7 +4,7 @@ #include "ui/views/mus/window_tree_host_mus.h" -#include "components/mus/public/cpp/view_tree_connection.h" +#include "components/mus/public/cpp/window_tree_connection.h" #include "mojo/application/public/interfaces/shell.mojom.h" #include "mojo/converters/geometry/geometry_type_converters.h" #include "ui/aura/env.h" @@ -20,11 +20,11 @@ //////////////////////////////////////////////////////////////////////////////// // WindowTreeHostMojo, public: -WindowTreeHostMojo::WindowTreeHostMojo(mojo::Shell* shell, mus::View* view) - : view_(view), bounds_(view->bounds().To<gfx::Rect>()) { - view_->AddObserver(this); +WindowTreeHostMojo::WindowTreeHostMojo(mojo::Shell* shell, mus::Window* window) + : window_(window), bounds_(window->bounds().To<gfx::Rect>()) { + window_->AddObserver(this); - context_factory_.reset(new SurfaceContextFactory(shell, view_)); + context_factory_.reset(new SurfaceContextFactory(shell, window_)); // WindowTreeHost creates the compositor using the ContextFactory from // aura::Env. Install |context_factory_| there so that |context_factory_| is // picked up. @@ -36,12 +36,12 @@ aura::Env::GetInstance()->set_context_factory(default_context_factory); DCHECK_EQ(context_factory_.get(), compositor()->context_factory()); - input_method_.reset(new InputMethodMUS(this, view_)); + input_method_.reset(new InputMethodMUS(this, window_)); SetSharedInputMethod(input_method_.get()); } WindowTreeHostMojo::~WindowTreeHostMojo() { - view_->RemoveObserver(this); + window_->RemoveObserver(this); DestroyCompositor(); DestroyDispatcher(); } @@ -98,9 +98,9 @@ //////////////////////////////////////////////////////////////////////////////// // WindowTreeHostMojo, ViewObserver implementation: -void WindowTreeHostMojo::OnViewBoundsChanged(mus::View* view, - const mojo::Rect& old_bounds, - const mojo::Rect& new_bounds) { +void WindowTreeHostMojo::OnWindowBoundsChanged(mus::Window* window, + const mojo::Rect& old_bounds, + const mojo::Rect& new_bounds) { gfx::Rect old_bounds2 = old_bounds.To<gfx::Rect>(); gfx::Rect new_bounds2 = new_bounds.To<gfx::Rect>(); bounds_ = new_bounds2;
diff --git a/ui/views/mus/window_tree_host_mus.h b/ui/views/mus/window_tree_host_mus.h index a535195..4de4a01 100644 --- a/ui/views/mus/window_tree_host_mus.h +++ b/ui/views/mus/window_tree_host_mus.h
@@ -6,7 +6,7 @@ #define UI_VIEWS_MUS_WINDOW_TREE_HOST_MUS_H_ #include "base/macros.h" -#include "components/mus/public/cpp/view_observer.h" +#include "components/mus/public/cpp/window_observer.h" #include "ui/aura/window_tree_host.h" #include "ui/events/event_source.h" #include "ui/gfx/geometry/rect.h" @@ -27,9 +27,9 @@ class SurfaceContextFactory; class WindowTreeHostMojo : public aura::WindowTreeHost, - public mus::ViewObserver { + public mus::WindowObserver { public: - WindowTreeHostMojo(mojo::Shell* shell, mus::View* view); + WindowTreeHostMojo(mojo::Shell* shell, mus::Window* window); ~WindowTreeHostMojo() override; const gfx::Rect& bounds() const { return bounds_; } @@ -53,12 +53,12 @@ void MoveCursorToNative(const gfx::Point& location) override; void OnCursorVisibilityChangedNative(bool show) override; - // mus::ViewObserver: - void OnViewBoundsChanged(mus::View* view, - const mojo::Rect& old_bounds, - const mojo::Rect& new_bounds) override; + // mus::WindowObserver: + void OnWindowBoundsChanged(mus::Window* window, + const mojo::Rect& old_bounds, + const mojo::Rect& new_bounds) override; - mus::View* view_; + mus::Window* window_; gfx::Rect bounds_;
diff --git a/ui/webui/resources/cr_elements/v1_0/network/cr_network_list.css b/ui/webui/resources/cr_elements/v1_0/network/cr_network_list.css index b4d5de05..9d6293b 100644 --- a/ui/webui/resources/cr_elements/v1_0/network/cr_network_list.css +++ b/ui/webui/resources/cr_elements/v1_0/network/cr_network_list.css
@@ -3,7 +3,6 @@ * found in the LICENSE file. */ #container { - border: 1px solid; max-height: 1000px; min-height: 50px; overflow-y: auto; @@ -13,3 +12,7 @@ #networkList { flex: 1; } + +cr-network-list-item:not(:last-of-type) { + border-bottom: 1px solid lightgrey; +}
diff --git a/ui/webui/resources/cr_elements/v1_0/policy/compiled_resources.gyp b/ui/webui/resources/cr_elements/v1_0/policy/compiled_resources.gyp index 801f44a..a8701111 100644 --- a/ui/webui/resources/cr_elements/v1_0/policy/compiled_resources.gyp +++ b/ui/webui/resources/cr_elements/v1_0/policy/compiled_resources.gyp
@@ -4,13 +4,39 @@ { 'targets': [ { - 'target_name': 'cr_policy_indicator', + 'target_name': 'cr_policy_indicator_behavior', + 'variables': { + 'depends': [ + '../../../../../../ui/webui/resources/js/compiled_resources.gyp:assert', + '../../../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data', + ], + }, + 'includes': ['../../../../../../third_party/closure_compiler/compile_js.gypi'], + }, + { + 'target_name': 'cr_policy_pref_behavior', 'variables': { 'depends': [ '../../../../../../third_party/polymer/v1_0/components-chromium/iron-iconset-svg/iron-iconset-svg-extracted.js', '../../../../../../third_party/polymer/v1_0/components-chromium/iron-meta/iron-meta-extracted.js', '../../../../../../ui/webui/resources/js/compiled_resources.gyp:assert', '../../../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data', + 'cr_policy_indicator_behavior.js', + ], + 'externs': [ + '../../../../../../third_party/closure_compiler/externs/settings_private.js' + ], + }, + 'includes': ['../../../../../../third_party/closure_compiler/compile_js.gypi'], + }, + { + 'target_name': 'cr_policy_pref_indicator', + 'variables': { + 'depends': [ + '../../../../../../ui/webui/resources/js/compiled_resources.gyp:assert', + '../../../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data', + 'cr_policy_indicator_behavior.js', + 'cr_policy_pref_behavior.js', ], 'externs': [ '../../../../../../third_party/closure_compiler/externs/settings_private.js'
diff --git a/ui/webui/resources/cr_elements/v1_0/policy/cr_policy_indicator.html b/ui/webui/resources/cr_elements/v1_0/policy/cr_policy_indicator.html deleted file mode 100644 index ea2ead1..0000000 --- a/ui/webui/resources/cr_elements/v1_0/policy/cr_policy_indicator.html +++ /dev/null
@@ -1,18 +0,0 @@ -<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/iron-icons.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/social-icons.html"> - -<dom-module id="cr-policy-indicator"> - <link rel="import" type="css" href="cr_policy_indicator.css"> - <template> - <div class="layout horizontal"> - <iron-icon id="indicator" - hidden$="[[!isIndicatorVisible_(indicatorType)]]" - icon="[[getIcon_(indicatorType)]]" - title$="[[getTooltipText_(indicatorType, pref, controllingUser)]]"> - </iron-icon> - </div> - </template> - <script src="cr_policy_indicator.js"></script> -</dom-module>
diff --git a/ui/webui/resources/cr_elements/v1_0/policy/cr_policy_indicator.js b/ui/webui/resources/cr_elements/v1_0/policy/cr_policy_indicator.js deleted file mode 100644 index d9248c5..0000000 --- a/ui/webui/resources/cr_elements/v1_0/policy/cr_policy_indicator.js +++ /dev/null
@@ -1,151 +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. - -/** - * @fileoverview Polymer element for indicating policies that apply to an - * element controlling a settings preference. - */ - -var CrPolicyIndicator = { - /** @enum {string} */ - Type: { - DEVICE_POLICY: 'devicePolicy', - EXTENSION: 'extension', - NONE: 'none', - OWNER: 'owner', - PRIMARY_USER: 'primary_user', - RECOMMENDED: 'recommended', - USER_POLICY: 'userPolicy', - }, -}; - -(function() { - -/** @element cr-policy-indicator */ -Polymer({ - is: 'cr-policy-indicator', - - properties: { - /** - * Optional preference object associated with the indicator. Initialized to - * null so that computed functions will get called if this is never set. - * @type {?chrome.settingsPrivate.PrefObject} - */ - pref: {type: Object, value: null}, - - /** - * Optional email of the user controlling the setting when the setting does - * not correspond to a pref (Chrome OS only). Only used when pref is null. - * Initialized to '' so that computed functions will get called if this is - * never set. - */ - controllingUser: {type: String, value: ''}, - - /** - * Which indicator type to show (or NONE). - * @type {CrPolicyIndicator.Type} - */ - indicatorType: {type: String, value: CrPolicyIndicator.Type.NONE}, - }, - - observers: ['prefPolicyChanged_(pref.policySource, pref.policyEnforcement)'], - - /** - * Polymer observer for pref. - * @param {chrome.settingsPrivate.PolicySource} source - * @param {chrome.settingsPrivate.PolicyEnforcement} enforcement - * @private - */ - prefPolicyChanged_: function(source, enforcement) { - var type = CrPolicyIndicator.Type.NONE; - if (enforcement == chrome.settingsPrivate.PolicyEnforcement.ENFORCED) { - if (source == chrome.settingsPrivate.PolicySource.PRIMARY_USER) - type = CrPolicyIndicator.Type.PRIMARY_USER; - else if (source == chrome.settingsPrivate.PolicySource.OWNER) - type = CrPolicyIndicator.Type.OWNER; - else if (source == chrome.settingsPrivate.PolicySource.USER_POLICY) - type = CrPolicyIndicator.Type.USER_POLICY; - else if (source == chrome.settingsPrivate.PolicySource.DEVICE_POLICY) - type = CrPolicyIndicator.Type.DEVICE_POLICY; - else if (source == chrome.settingsPrivate.PolicySource.EXTENSION) - type = CrPolicyIndicator.Type.EXTENSION; - } else if (enforcement == - chrome.settingsPrivate.PolicyEnforcement.RECOMMENDED) { - type = CrPolicyIndicator.Type.RECOMMENDED; - } - this.indicatorType = type; - }, - - /** - * @param {CrPolicyIndicator.Type} type - * @return {boolean} True if the indicator should be shown. - * @private - */ - isIndicatorVisible_: function(type) { - return type != CrPolicyIndicator.Type.NONE; - }, - - /** - * @param {CrPolicyIndicator.Type} type - * @return {string} The iron-icons icon name. - * @private - */ - getIcon_: function(type) { - switch (type) { - case CrPolicyIndicator.Type.NONE: - return ''; - case CrPolicyIndicator.Type.PRIMARY_USER: - return 'social:group'; - case CrPolicyIndicator.Type.OWNER: - return 'social:person'; - case CrPolicyIndicator.Type.USER_POLICY: - case CrPolicyIndicator.Type.DEVICE_POLICY: - return 'social:domain'; - case CrPolicyIndicator.Type.EXTENSION: - return 'extension'; - case CrPolicyIndicator.Type.RECOMMENDED: - return 'social:domain'; - } - assertNotReached(); - }, - - /** - * @param {string} id The id of the string to translate. - * @param {string=} opt_name An optional name argument. - * @return The translated string. - */ - i18n_: function (id, opt_name) { - return loadTimeData.getStringF(id, opt_name); - }, - - /** - * @param {CrPolicyIndicator.Type} type The type of indicator. - * @param {?chrome.settingsPrivate.PrefObject} pref - * @param {string} controllingUser The user controlling the setting, if |pref| - * is null. - * @return {string} The tooltip text for |type|. - * @private - */ - getTooltipText_: function(type, pref, controllingUser) { - var name = pref ? pref.policySourceName : controllingUser; - - switch (type) { - case CrPolicyIndicator.Type.PRIMARY_USER: - return this.i18n_('controlledSettingShared', name); - case CrPolicyIndicator.Type.OWNER: - return this.i18n_('controlledSettingOwner', name); - case CrPolicyIndicator.Type.USER_POLICY: - case CrPolicyIndicator.Type.DEVICE_POLICY: - return this.i18n_('controlledSettingPolicy'); - case CrPolicyIndicator.Type.EXTENSION: - return this.i18n_('controlledSettingExtension', name); - case CrPolicyIndicator.Type.RECOMMENDED: - if (pref && pref.value == pref.recommendedValue) - return this.i18n_('controlledSettingRecommendedMatches'); - return this.i18n_('controlledSettingRecommendedDiffers'); - } - return ''; - } -}); -})();
diff --git a/ui/webui/resources/cr_elements/v1_0/policy/cr_policy_indicator_behavior.html b/ui/webui/resources/cr_elements/v1_0/policy/cr_policy_indicator_behavior.html new file mode 100644 index 0000000..518e6c1 --- /dev/null +++ b/ui/webui/resources/cr_elements/v1_0/policy/cr_policy_indicator_behavior.html
@@ -0,0 +1 @@ +<script src="cr_policy_indicator_behavior.js"></script>
diff --git a/ui/webui/resources/cr_elements/v1_0/policy/cr_policy_indicator_behavior.js b/ui/webui/resources/cr_elements/v1_0/policy/cr_policy_indicator_behavior.js new file mode 100644 index 0000000..dc474f0a --- /dev/null +++ b/ui/webui/resources/cr_elements/v1_0/policy/cr_policy_indicator_behavior.js
@@ -0,0 +1,89 @@ +// 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. + +/** + * @fileoverview Behavior for policy controlled indicators. + */ + +/** @enum {string} */ +var CrPolicyIndicatorType = { + DEVICE_POLICY: 'devicePolicy', + EXTENSION: 'extension', + NONE: 'none', + OWNER: 'owner', + PRIMARY_USER: 'primary_user', + RECOMMENDED: 'recommended', + USER_POLICY: 'userPolicy', +}; + +/** @polymerBehavior */ +var CrPolicyIndicatorBehavior = { + /** + * @param {CrPolicyIndicatorType} type + * @return {boolean} True if the indicator should be shown. + * @private + */ + isIndicatorVisible: function(type) { + return type != CrPolicyIndicatorType.NONE; + }, + + /** + * @param {CrPolicyIndicatorType} type + * @return {string} The iron-icons icon name. + * @private + */ + getPolicyIndicatorIcon: function(type) { + switch (type) { + case CrPolicyIndicatorType.NONE: + return ''; + case CrPolicyIndicatorType.PRIMARY_USER: + return 'social:group'; + case CrPolicyIndicatorType.OWNER: + return 'social:person'; + case CrPolicyIndicatorType.USER_POLICY: + case CrPolicyIndicatorType.DEVICE_POLICY: + return 'social:domain'; + case CrPolicyIndicatorType.EXTENSION: + return 'extension'; + case CrPolicyIndicatorType.RECOMMENDED: + return 'social:domain'; + } + assertNotReached(); + return ''; + }, + + /** + * @param {string} id The id of the string to translate. + * @param {string=} opt_name An optional name argument. + * @return The translated string. + */ + i18n_: function (id, opt_name) { + return loadTimeData.getStringF(id, opt_name); + }, + + /** + * @param {CrPolicyIndicatorType} type + * @param {string} name The name associated with the controllable. See + * chrome.settingsPrivate.PrefObject.policySourceName + * @return {string} The tooltip text for |type|. + */ + getPolicyIndicatorTooltip: function(type, name) { + switch (type) { + case CrPolicyIndicatorType.PRIMARY_USER: + return this.i18n_('controlledSettingShared', name); + case CrPolicyIndicatorType.OWNER: + return this.i18n_('controlledSettingOwner', name); + case CrPolicyIndicatorType.USER_POLICY: + case CrPolicyIndicatorType.DEVICE_POLICY: + return this.i18n_('controlledSettingPolicy'); + case CrPolicyIndicatorType.EXTENSION: + return this.i18n_('controlledSettingExtension', name); + case CrPolicyIndicatorType.RECOMMENDED: + // This case is not handled here since it requires knowledge of the + // value and recommended value associated with the controllable. + assertNotReached(); + } + return ''; + } +};
diff --git a/ui/webui/resources/cr_elements/v1_0/policy/cr_policy_pref_behavior.html b/ui/webui/resources/cr_elements/v1_0/policy/cr_policy_pref_behavior.html new file mode 100644 index 0000000..ab7bc58 --- /dev/null +++ b/ui/webui/resources/cr_elements/v1_0/policy/cr_policy_pref_behavior.html
@@ -0,0 +1 @@ +<script src="cr_policy_pref_behavior.js"></script>
diff --git a/ui/webui/resources/cr_elements/v1_0/policy/cr_policy_pref_behavior.js b/ui/webui/resources/cr_elements/v1_0/policy/cr_policy_pref_behavior.js new file mode 100644 index 0000000..d8897da6 --- /dev/null +++ b/ui/webui/resources/cr_elements/v1_0/policy/cr_policy_pref_behavior.js
@@ -0,0 +1,45 @@ +// 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. + +/** + * @fileoverview Behavior for policy controlled settings prefs. + */ + +/** @polymerBehavior */ +var CrPolicyPrefBehavior = { + /** + * @param {!chrome.settingsPrivate.PrefObject} pref + * @return {boolean} True if the pref is controlled by an enforced policy. + */ + isPrefPolicyControlled: function(pref) { + return pref.policyEnforcement == + chrome.settingsPrivate.PolicyEnforcement.ENFORCED; + }, + + /** + * @param {chrome.settingsPrivate.PolicySource} source + * @param {chrome.settingsPrivate.PolicyEnforcement} enforcement + * @return {CrPolicyIndicatorType} The indicator type based on |source| and + * |enforcement|. + */ + getIndicatorType: function(source, enforcement) { + if (enforcement == chrome.settingsPrivate.PolicyEnforcement.RECOMMENDED) + return CrPolicyIndicatorType.RECOMMENDED; + if (enforcement == chrome.settingsPrivate.PolicyEnforcement.ENFORCED) { + switch (source) { + case chrome.settingsPrivate.PolicySource.PRIMARY_USER: + return CrPolicyIndicatorType.PRIMARY_USER; + case chrome.settingsPrivate.PolicySource.OWNER: + return CrPolicyIndicatorType.OWNER; + case chrome.settingsPrivate.PolicySource.USER_POLICY: + return CrPolicyIndicatorType.USER_POLICY; + case chrome.settingsPrivate.PolicySource.DEVICE_POLICY: + return CrPolicyIndicatorType.DEVICE_POLICY; + case chrome.settingsPrivate.PolicySource.EXTENSION: + return CrPolicyIndicatorType.EXTENSION; + } + } + return CrPolicyIndicatorType.NONE; + }, +};
diff --git a/ui/webui/resources/cr_elements/v1_0/policy/cr_policy_pref_indicator.html b/ui/webui/resources/cr_elements/v1_0/policy/cr_policy_pref_indicator.html new file mode 100644 index 0000000..56bc23d1 --- /dev/null +++ b/ui/webui/resources/cr_elements/v1_0/policy/cr_policy_pref_indicator.html
@@ -0,0 +1,20 @@ +<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/iron-icons.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/social-icons.html"> +<link rel="import" href="cr_policy_indicator_behavior.html"> +<link rel="import" href="cr_policy_pref_behavior.html"> + +<dom-module id="cr-policy-pref-indicator"> + <link rel="import" type="css" href="cr_policy_indicator.css"> + <template> + <div class="layout horizontal"> + <iron-icon id="indicator" + hidden$="[[!isIndicatorVisible(indicatorType)]]" + icon="[[getPolicyIndicatorIcon(indicatorType)]]" + title$="[[getPolicyIndicatorTooltip(indicatorType, pref, controllingUser)]]"> + </iron-icon> + </div> + </template> + <script src="cr_policy_pref_indicator.js"></script> +</dom-module>
diff --git a/ui/webui/resources/cr_elements/v1_0/policy/cr_policy_pref_indicator.js b/ui/webui/resources/cr_elements/v1_0/policy/cr_policy_pref_indicator.js new file mode 100644 index 0000000..769ba62f --- /dev/null +++ b/ui/webui/resources/cr_elements/v1_0/policy/cr_policy_pref_indicator.js
@@ -0,0 +1,59 @@ +// 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. + +/** + * @fileoverview Polymer element for indicating policies that apply to an + * element controlling a settings preference. + * + * @element cr-policy-pref-indicator + */ +Polymer({ + is: 'cr-policy-pref-indicator', + + behaviors: [CrPolicyIndicatorBehavior, CrPolicyPrefBehavior], + + properties: { + /** + * Optional preference object associated with the indicator. Initialized to + * null so that computed functions will get called if this is never set. + * @type {?chrome.settingsPrivate.PrefObject} + */ + pref: {type: Object, value: null}, + + /** + * Optional email of the user controlling the setting when the setting does + * not correspond to a pref (Chrome OS only). Only used when pref is null. + * Initialized to '' so that computed functions will get called if this is + * never set. TODO(stevenjb/michaelpg): Create a separate indicator for + * non-pref (i.e. explicitly set) indicators (see languyage_detail_page). + */ + controllingUser: {type: String, value: ''}, + + /** + * Which indicator type to show (or NONE). + * @type {CrPolicyIndicatorType} + */ + indicatorType: { + type: String, + value: CrPolicyIndicatorType.NONE, + computed: 'getIndicatorType(pref.policySource, pref.policyEnforcement)', + }, + }, + + /** + * @param {CrPolicyIndicatorType} type + * @param {?chrome.settingsPrivate.PrefObject} pref + * @return {string} The tooltip text for |type|. + * @private + */ + getTooltip_: function(type, pref, controllingUser) { + if (type == CrPolicyIndicatorType.RECOMMENDED) { + if (pref && pref.value == pref.recommendedValue) + return this.i18n_('controlledSettingRecommendedMatches'); + return this.i18n_('controlledSettingRecommendedDiffers'); + } + var name = pref ? pref.policySourceName : controllingUser; + return this.getPolicyIndicatorTooltip(type, name); + } +});
diff --git a/ui/webui/resources/cr_elements_resources.grdp b/ui/webui/resources/cr_elements_resources.grdp index 6b781428..f687d82 100644 --- a/ui/webui/resources/cr_elements_resources.grdp +++ b/ui/webui/resources/cr_elements_resources.grdp
@@ -87,11 +87,23 @@ <structure name="IDR_CR_ELEMENTS_1_0_CR_POLICY_INDICATOR_CSS" file="../../webui/resources/cr_elements/v1_0/policy/cr_policy_indicator.css" type="chrome_html" /> - <structure name="IDR_CR_ELEMENTS_1_0_CR_POLICY_INDICATOR_HTML" - file="../../webui/resources/cr_elements/v1_0/policy/cr_policy_indicator.html" + <structure name="IDR_CR_ELEMENTS_1_0_CR_POLICY_INDICATOR_BEHAVIOR_HTML" + file="../../webui/resources/cr_elements/v1_0/policy/cr_policy_indicator_behavior.html" type="chrome_html" /> - <structure name="IDR_CR_ELEMENTS_1_0_CR_POLICY_INDICATOR_JS" - file="../../webui/resources/cr_elements/v1_0/policy/cr_policy_indicator.js" + <structure name="IDR_CR_ELEMENTS_1_0_CR_POLICY_INDICATOR_BEHAVIOR_JS" + file="../../webui/resources/cr_elements/v1_0/policy/cr_policy_indicator_behavior.js" + type="chrome_html" /> + <structure name="IDR_CR_ELEMENTS_1_0_CR_POLICY_PREF_BEHAVIOR_HTML" + file="../../webui/resources/cr_elements/v1_0/policy/cr_policy_pref_behavior.html" + type="chrome_html" /> + <structure name="IDR_CR_ELEMENTS_1_0_CR_POLICY_PREF_BEHAVIOR_JS" + file="../../webui/resources/cr_elements/v1_0/policy/cr_policy_pref_behavior.js" + type="chrome_html" /> + <structure name="IDR_CR_ELEMENTS_1_0_CR_POLICY_PREF_INDICATOR_JS" + file="../../webui/resources/cr_elements/v1_0/policy/cr_policy_pref_indicator.js" + type="chrome_html" /> + <structure name="IDR_CR_ELEMENTS_1_0_CR_POLICY_PREF_INDICATOR_HTML" + file="../../webui/resources/cr_elements/v1_0/policy/cr_policy_pref_indicator.html" type="chrome_html" /> <structure name="IDR_CR_ELEMENTS_1_0_CR_SEARCH_FIELD_CSS" file="../../webui/resources/cr_elements/v1_0/cr_search_field/cr_search_field.css"
diff --git a/ui/webui/resources/css/roboto.css b/ui/webui/resources/css/roboto.css index 776fa92..34c0ad7 100644 --- a/ui/webui/resources/css/roboto.css +++ b/ui/webui/resources/css/roboto.css
@@ -7,9 +7,7 @@ font-style: normal; font-weight: 400; src: local('Roboto'), local('Roboto-Regular'), - url(chrome://resources/roboto/roboto-regular-latin.woff2) format('woff2'); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, - U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000; + url(chrome://resources/roboto/roboto-regular.woff2) format('woff2'); } @font-face { @@ -17,7 +15,5 @@ font-style: normal; font-weight: 500; src: local('Roboto Medium'), local('Roboto-Medium'), - url(chrome://resources/roboto/roboto-medium-latin.woff2) format('woff2'); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, - U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000; + url(chrome://resources/roboto/roboto-medium.woff2) format('woff2'); }
diff --git a/ui/webui/resources/js/cr/ui/table.js b/ui/webui/resources/js/cr/ui/table.js index 6a2640086..3e7b301 100644 --- a/ui/webui/resources/js/cr/ui/table.js +++ b/ui/webui/resources/js/cr/ui/table.js
@@ -218,7 +218,6 @@ /** * Ensures that a given index is inside the viewport. * @param {number} i The index of the item to scroll into view. - * @return {boolean} Whether any scrolling was needed. */ scrollIndexIntoView: function(i) { this.list_.scrollIndexIntoView(i);
diff --git a/ui/webui/resources/roboto/roboto-medium-latin.woff2 b/ui/webui/resources/roboto/roboto-medium-latin.woff2 deleted file mode 100644 index 5f96609d..0000000 --- a/ui/webui/resources/roboto/roboto-medium-latin.woff2 +++ /dev/null Binary files differ
diff --git a/ui/webui/resources/roboto/roboto-medium.woff2 b/ui/webui/resources/roboto/roboto-medium.woff2 new file mode 100644 index 0000000..ad8f5bc --- /dev/null +++ b/ui/webui/resources/roboto/roboto-medium.woff2 Binary files differ
diff --git a/ui/webui/resources/roboto/roboto-regular-latin.woff2 b/ui/webui/resources/roboto/roboto-regular-latin.woff2 deleted file mode 100644 index 120796b..0000000 --- a/ui/webui/resources/roboto/roboto-regular-latin.woff2 +++ /dev/null Binary files differ
diff --git a/ui/webui/resources/roboto/roboto-regular.woff2 b/ui/webui/resources/roboto/roboto-regular.woff2 new file mode 100644 index 0000000..bf6ecad --- /dev/null +++ b/ui/webui/resources/roboto/roboto-regular.woff2 Binary files differ
diff --git a/ui/webui/resources/webui_resources.grd b/ui/webui/resources/webui_resources.grd index 50af42a..fa62cbd 100644 --- a/ui/webui/resources/webui_resources.grd +++ b/ui/webui/resources/webui_resources.grd
@@ -16,9 +16,12 @@ <include name="IDR_WEBUI_I18N_TEMPLATE_JS" file="js/i18n_template.js" flattenhtml="true" type="BINDATA" /> <include name="IDR_WEBUI_JSTEMPLATE_JS" file="js/jstemplate_compiled.js" flattenhtml="true" type="BINDATA" /> <include name="IDR_WEBUI_ANALYTICS_JS" file="js/analytics.js" flattenhtml="true" type="BINDATA" /> - <!-- Roboto Font --> - <include name="IDR_WEBUI_ROBOTO_ROBOTO_REGULAR_LATIN_WOFF2" file="roboto/roboto-regular-latin.woff2" type="BINDATA" /> - <include name="IDR_WEBUI_ROBOTO_ROBOTO_MEDIUM_LATIN_WOFF2" file="roboto/roboto-medium-latin.woff2" type="BINDATA" /> + <!-- Roboto Font. Roboto-Regular is already available on Android, and + Roboto-Medium is not used on Android. --> + <if expr="not android"> + <include name="IDR_WEBUI_ROBOTO_ROBOTO_REGULAR_WOFF2" file="roboto/roboto-regular.woff2" type="BINDATA" /> + <include name="IDR_WEBUI_ROBOTO_ROBOTO_MEDIUM_WOFF2" file="roboto/roboto-medium.woff2" type="BINDATA" /> + </if> <!-- Component apps common image resources - 1x --> <!-- White button -->