diff options
author | Torne (Richard Coles) <torne@google.com> | 2013-05-29 14:40:03 +0100 |
---|---|---|
committer | Torne (Richard Coles) <torne@google.com> | 2013-05-29 14:40:03 +0100 |
commit | 90dce4d38c5ff5333bea97d859d4e484e27edf0c (patch) | |
tree | 9c51c7dd97d24b15befa97a3482c51851e5383a1 /content/browser | |
parent | 1515035f5917d10d363b0888a3615d581ad8b83f (diff) | |
download | chromium_org-90dce4d38c5ff5333bea97d859d4e484e27edf0c.tar.gz |
Merge from Chromium at DEPS revision r202854
This commit was generated by merge_to_master.py.
Change-Id: Idca323f71ef844a9e04f454d4f070b1e398f2deb
Diffstat (limited to 'content/browser')
223 files changed, 5570 insertions, 8351 deletions
diff --git a/content/browser/DEPS b/content/browser/DEPS index 58447db2bf..592f4afd67 100644 --- a/content/browser/DEPS +++ b/content/browser/DEPS @@ -1,5 +1,4 @@ include_rules = [ - "+components/tracing", "+content/gpu", # For gpu_info_collector.h and in-process GPU "+content/port/browser", "+content/public/browser", @@ -9,6 +8,11 @@ include_rules = [ "+ui/webui", "+win8/util", + # TODO(joi): This was misplaced; need to move it somewhere else, + # since //content shouldn't depend on //components, which is a layer + # above. + "+components/tracing", + # Other libraries. "+third_party/iaccessible2", "+third_party/isimpledom", @@ -22,7 +26,7 @@ include_rules = [ "-webkit/renderer", - # DO NOT ADD ANY CHROME INCLUDES HERE!!! + # DO NOT ADD ANY CHROME OR COMPONENTS INCLUDES HERE!!! # See https://sites.google.com/a/chromium.org/dev/developers/content-module # for more information. ] diff --git a/content/browser/OWNERS b/content/browser/OWNERS index c269ca3edd..2d2ca32803 100644 --- a/content/browser/OWNERS +++ b/content/browser/OWNERS @@ -4,3 +4,7 @@ per-file child_process_security_policy_impl.cc=tsepez@chromium.org per-file child_process_security_policy_impl.cc=creis@chromium.org per-file child_process_security_policy_impl.cc=cevans@chromium.org per-file power_save_blocker_chromeos.cc=derat@chromium.org + +# Mac Sandbox profiles. +per-file *.sb=set noparent +per-file *.sb=jeremy@chromium.org diff --git a/content/browser/accessibility/accessibility_win_browsertest.cc b/content/browser/accessibility/accessibility_win_browsertest.cc index b099af9d21..d0800f1614 100644 --- a/content/browser/accessibility/accessibility_win_browsertest.cc +++ b/content/browser/accessibility/accessibility_win_browsertest.cc @@ -432,7 +432,7 @@ string16 AccessibleChecker::RoleVariantToString( IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, MAYBE(TestBusyAccessibilityTree)) { - NavigateToURL(shell(), GURL(chrome::kAboutBlankURL)); + NavigateToURL(shell(), GURL(kAboutBlankURL)); // The initial accessible returned should have state STATE_SYSTEM_BUSY while // the accessibility tree is being requested from the renderer. @@ -476,7 +476,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, EXPECT_NE(parent_dispatch, reinterpret_cast<IDispatch*>(NULL)); // Navigate to another page. - NavigateToURL(shell(), GURL(chrome::kAboutBlankURL)); + NavigateToURL(shell(), GURL(kAboutBlankURL)); // Verify that the IAccessible reference still points to a valid object and // that calls to its methods fail since the tree is no longer valid after diff --git a/content/browser/accessibility/browser_accessibility_manager_win.cc b/content/browser/accessibility/browser_accessibility_manager_win.cc index 33e4614771..b956d218d3 100644 --- a/content/browser/accessibility/browser_accessibility_manager_win.cc +++ b/content/browser/accessibility/browser_accessibility_manager_win.cc @@ -53,6 +53,12 @@ AccessibilityNodeData BrowserAccessibilityManagerWin::GetEmptyDocument() { return empty_document; } +void BrowserAccessibilityManagerWin::MaybeCallNotifyWinEvent(DWORD event, + LONG child_id) { + if (parent_iaccessible()) + ::NotifyWinEvent(event, parent_hwnd(), OBJID_CLIENT, child_id); +} + void BrowserAccessibilityManagerWin::AddNodeToMap(BrowserAccessibility* node) { BrowserAccessibilityManager::AddNodeToMap(node); LONG unique_id_win = node->ToBrowserAccessibilityWin()->unique_id_win(); @@ -151,14 +157,14 @@ void BrowserAccessibilityManagerWin::NotifyAccessibilityEvent( break; } - // Pass the node's unique id in the |child_id| argument to NotifyWinEvent; - // the AT client will then call get_accChild on the HWND's accessibility - // object and pass it that same id, which we can use to retrieve the - // IAccessible for this node. - LONG child_id = node->ToBrowserAccessibilityWin()->unique_id_win(); - - if (event_id != EVENT_MIN) - NotifyWinEvent(event_id, parent_hwnd(), OBJID_CLIENT, child_id); + if (event_id != EVENT_MIN) { + // Pass the node's unique id in the |child_id| argument to NotifyWinEvent; + // the AT client will then call get_accChild on the HWND's accessibility + // object and pass it that same id, which we can use to retrieve the + // IAccessible for this node. + LONG child_id = node->ToBrowserAccessibilityWin()->unique_id_win(); + MaybeCallNotifyWinEvent(event_id, child_id); + } // If this is a layout complete notification (sent when a container scrolls) // and there is a descendant tracked object, send a notification on it. @@ -166,10 +172,8 @@ void BrowserAccessibilityManagerWin::NotifyAccessibilityEvent( if (type == AccessibilityNotificationLayoutComplete && tracked_scroll_object_ && tracked_scroll_object_->IsDescendantOf(node)) { - NotifyWinEvent( + MaybeCallNotifyWinEvent( IA2_EVENT_VISIBLE_DATA_CHANGED, - parent_hwnd(), - OBJID_CLIENT, tracked_scroll_object_->ToBrowserAccessibilityWin()->unique_id_win()); tracked_scroll_object_->Release(); tracked_scroll_object_ = NULL; diff --git a/content/browser/accessibility/browser_accessibility_manager_win.h b/content/browser/accessibility/browser_accessibility_manager_win.h index e82f0656a9..7aec2e1c5e 100644 --- a/content/browser/accessibility/browser_accessibility_manager_win.h +++ b/content/browser/accessibility/browser_accessibility_manager_win.h @@ -37,6 +37,9 @@ class CONTENT_EXPORT BrowserAccessibilityManagerWin parent_iaccessible_ = parent_iaccessible; } + // Calls NotifyWinEvent if the parent window's IAccessible pointer is known. + void MaybeCallNotifyWinEvent(DWORD event, LONG child_id); + // BrowserAccessibilityManager methods virtual void AddNodeToMap(BrowserAccessibility* node); virtual void RemoveNode(BrowserAccessibility* node) OVERRIDE; diff --git a/content/browser/accessibility/browser_accessibility_win.cc b/content/browser/accessibility/browser_accessibility_win.cc index 7f5bc0185f..263c0944ba 100644 --- a/content/browser/accessibility/browser_accessibility_win.cc +++ b/content/browser/accessibility/browser_accessibility_win.cc @@ -491,6 +491,10 @@ STDMETHODIMP BrowserAccessibilityWin::get_accParent(IDispatch** disp_parent) { // This happens if we're the root of the tree; // return the IAccessible for the window. parent = manager_->ToBrowserAccessibilityManagerWin()->parent_iaccessible(); + // |parent| can only be NULL if the manager was created before the parent + // IAccessible was known and it wasn't subsequently set before a client + // requested it. Crash hard if this happens so that we get crash reports. + CHECK(parent); } parent->AddRef(); @@ -2941,10 +2945,11 @@ void BrowserAccessibilityWin::PostInitialize() { previous_text_ = text; } - HWND hwnd = manager_->ToBrowserAccessibilityManagerWin()->parent_hwnd(); - // Fire events if the state has changed. if (!first_time_ && ia_state_ != old_ia_state_) { + BrowserAccessibilityManagerWin* manager = + manager_->ToBrowserAccessibilityManagerWin(); + // Normally focus events are handled elsewhere, however // focus for managed descendants is platform-specific. // Fire a focus event if the focused descendant in a multi-select @@ -2954,18 +2959,17 @@ void BrowserAccessibilityWin::PostInitialize() { (ia_state_ & STATE_SYSTEM_SELECTABLE) && (ia_state_ & STATE_SYSTEM_FOCUSED) && !(old_ia_state_ & STATE_SYSTEM_FOCUSED)) { - ::NotifyWinEvent(EVENT_OBJECT_FOCUS, hwnd, - OBJID_CLIENT, unique_id_win()); + manager->MaybeCallNotifyWinEvent(EVENT_OBJECT_FOCUS, unique_id_win()); } if ((ia_state_ & STATE_SYSTEM_SELECTED) && !(old_ia_state_ & STATE_SYSTEM_SELECTED)) { - ::NotifyWinEvent(EVENT_OBJECT_SELECTIONADD, hwnd, - OBJID_CLIENT, unique_id_win()); + manager->MaybeCallNotifyWinEvent(EVENT_OBJECT_SELECTIONADD, + unique_id_win()); } else if (!(ia_state_ & STATE_SYSTEM_SELECTED) && (old_ia_state_ & STATE_SYSTEM_SELECTED)) { - ::NotifyWinEvent(EVENT_OBJECT_SELECTIONREMOVE, hwnd, - OBJID_CLIENT, unique_id_win()); + manager->MaybeCallNotifyWinEvent(EVENT_OBJECT_SELECTIONREMOVE, + unique_id_win()); } old_ia_state_ = ia_state_; @@ -2988,9 +2992,8 @@ bool BrowserAccessibilityWin::IsNative() const { void BrowserAccessibilityWin::SetLocation(const gfx::Rect& new_location) { BrowserAccessibility::SetLocation(new_location); - HWND hwnd = manager_->ToBrowserAccessibilityManagerWin()->parent_hwnd(); - ::NotifyWinEvent(EVENT_OBJECT_LOCATIONCHANGE, hwnd, - OBJID_CLIENT, unique_id_win()); + manager_->ToBrowserAccessibilityManagerWin()->MaybeCallNotifyWinEvent( + EVENT_OBJECT_LOCATIONCHANGE, unique_id_win()); } BrowserAccessibilityWin* BrowserAccessibilityWin::NewReference() { diff --git a/content/browser/android/child_process_launcher_android.cc b/content/browser/android/child_process_launcher_android.cc index e14813acb0..fe91f0fa2f 100644 --- a/content/browser/android/child_process_launcher_android.cc +++ b/content/browser/android/child_process_launcher_android.cc @@ -8,13 +8,13 @@ #include "base/android/jni_array.h" #include "base/logging.h" #include "base/memory/scoped_ptr.h" -#include "content/browser/android/media_player_manager_impl.h" #include "content/browser/renderer_host/compositor_impl_android.h" #include "content/browser/renderer_host/render_view_host_impl.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/render_process_host.h" #include "jni/ChildProcessLauncher_jni.h" #include "media/base/android/media_player_android.h" +#include "media/base/android/media_player_manager.h" #include "ui/gl/android/scoped_java_surface.h" using base::android::AttachCurrentThread; diff --git a/content/browser/android/content_startup_flags.cc b/content/browser/android/content_startup_flags.cc index 2c2f2bef3b..4af0854b39 100644 --- a/content/browser/android/content_startup_flags.cc +++ b/content/browser/android/content_startup_flags.cc @@ -59,6 +59,7 @@ void SetContentCommandLineFlags(int max_render_process_count, parsed_command_line->AppendSwitch(switches::kEnableGestureTapHighlight); parsed_command_line->AppendSwitch(switches::kEnablePinch); + parsed_command_line->AppendSwitch(switches::kEnableOverscrollNotifications); // Run the GPU service as a thread in the browser instead of as a // standalone process. @@ -68,9 +69,6 @@ void SetContentCommandLineFlags(int max_render_process_count, parsed_command_line->AppendSwitch(switches::kEnableFixedLayout); parsed_command_line->AppendSwitch(switches::kEnableViewport); - parsed_command_line->AppendSwitch( - cc::switches::kEnableCompositorFrameMessage); - if (!plugin_descriptor.empty()) { parsed_command_line->AppendSwitchNative( switches::kRegisterPepperPlugins, plugin_descriptor); diff --git a/content/browser/android/content_video_view.cc b/content/browser/android/content_video_view.cc index 7f71cc4805..3d4c259607 100644 --- a/content/browser/android/content_video_view.cc +++ b/content/browser/android/content_video_view.cc @@ -49,6 +49,12 @@ void ContentVideoView::DestroyContentVideoView() { } } +// static +void ContentVideoView::KeepScreenOn(bool screen_on) { + Java_ContentVideoView_keepScreenOnContentVideoView(AttachCurrentThread(), + screen_on); +} + void ContentVideoView::OnMediaPlayerError(int error_type) { if (!j_content_video_view_.is_null()) { Java_ContentVideoView_onMediaPlayerError(AttachCurrentThread(), diff --git a/content/browser/android/content_video_view.h b/content/browser/android/content_video_view.h index 49b8d0568c..ab0920c124 100644 --- a/content/browser/android/content_video_view.h +++ b/content/browser/android/content_video_view.h @@ -29,6 +29,7 @@ class ContentVideoView { ~ContentVideoView(); static bool RegisterContentVideoView(JNIEnv* env); + static void KeepScreenOn(bool screen_on); // Getter method called by the Java class to get the media information. int GetVideoWidth(JNIEnv*, jobject obj) const; diff --git a/content/browser/android/content_view_core_impl.cc b/content/browser/android/content_view_core_impl.cc index 8bc6e47463..c7104a1052 100644 --- a/content/browser/android/content_view_core_impl.cc +++ b/content/browser/android/content_view_core_impl.cc @@ -52,8 +52,8 @@ #include "ui/gfx/screen.h" #include "ui/gfx/size_conversions.h" #include "ui/gfx/size_f.h" +#include "webkit/common/user_agent/user_agent_util.h" #include "webkit/glue/webmenuitem.h" -#include "webkit/user_agent/user_agent_util.h" using base::android::AttachCurrentThread; using base::android::ConvertJavaStringToUTF16; @@ -699,6 +699,14 @@ void ContentViewCoreImpl::SetVSyncNotificationEnabled(bool enabled) { env, obj.obj(), static_cast<jboolean>(enabled)); } +void ContentViewCoreImpl::SetNeedsAnimate() { + JNIEnv* env = AttachCurrentThread(); + ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); + if (obj.is_null()) + return; + Java_ContentViewCore_setNeedsAnimate(env, obj.obj()); +} + ui::ViewAndroid* ContentViewCoreImpl::GetViewAndroid() const { // view_android_ should never be null for Chrome. DCHECK(view_android_); @@ -855,14 +863,6 @@ float ContentViewCoreImpl::GetDpiScale() const { return dpi_scale_; } -void ContentViewCoreImpl::SetInputHandler( - WebKit::WebCompositorInputHandler* input_handler) { - if (!input_event_filter_) - input_event_filter_.reset(new SyncInputEventFilter); - - input_event_filter_->SetInputHandler(input_handler); -} - void ContentViewCoreImpl::RequestContentClipping( const gfx::Rect& clipping, const gfx::Size& content_size) { @@ -1236,7 +1236,17 @@ void ContentViewCoreImpl::OnVSync(JNIEnv* env, jobject /* obj */, if (!view) return; - view->SendVSync(base::TimeTicks::FromInternalValue(frame_time_micros)); + view->SendBeginFrame( + base::TimeTicks::FromInternalValue(frame_time_micros)); +} + +jboolean ContentViewCoreImpl::OnAnimate(JNIEnv* env, jobject /* obj */, + jlong frame_time_micros) { + RenderWidgetHostViewAndroid* view = GetRenderWidgetHostViewAndroid(); + if (!view) + return false; + + return view->Animate(base::TimeTicks::FromInternalValue(frame_time_micros)); } jboolean ContentViewCoreImpl::PopulateBitmapFromCompositor(JNIEnv* env, @@ -1278,8 +1288,11 @@ void ContentViewCoreImpl::AttachExternalVideoSurface(JNIEnv* env, #if defined(GOOGLE_TV) RenderViewHostImpl* rvhi = static_cast<RenderViewHostImpl*>( web_contents_->GetRenderViewHost()); - if (rvhi && rvhi->media_player_manager()) { - rvhi->media_player_manager()->AttachExternalVideoSurface( + MediaPlayerManagerImpl* media_player_manager_impl = + rvhi ? static_cast<MediaPlayerManagerImpl*>(rvhi->media_player_manager()) + : NULL; + if (media_player_manager_impl) { + media_player_manager_impl->AttachExternalVideoSurface( static_cast<int>(player_id), jsurface); } #endif @@ -1291,8 +1304,11 @@ void ContentViewCoreImpl::DetachExternalVideoSurface(JNIEnv* env, #if defined(GOOGLE_TV) RenderViewHostImpl* rvhi = static_cast<RenderViewHostImpl*>( web_contents_->GetRenderViewHost()); - if (rvhi && rvhi->media_player_manager()) { - rvhi->media_player_manager()->DetachExternalVideoSurface( + MediaPlayerManagerImpl* media_player_manager_impl = + rvhi ? static_cast<MediaPlayerManagerImpl*>(rvhi->media_player_manager()) + : NULL; + if (media_player_manager_impl) { + media_player_manager_impl->DetachExternalVideoSurface( static_cast<int>(player_id)); } #endif diff --git a/content/browser/android/content_view_core_impl.h b/content/browser/android/content_view_core_impl.h index 0c311a63eb..b9edb67eae 100644 --- a/content/browser/android/content_view_core_impl.h +++ b/content/browser/android/content_view_core_impl.h @@ -60,8 +60,6 @@ class ContentViewCoreImpl : public ContentViewCore, float scale, gfx::Size* out_size) OVERRIDE; virtual float GetDpiScale() const OVERRIDE; - virtual void SetInputHandler( - WebKit::WebCompositorInputHandler* input_handler) OVERRIDE; virtual void RequestContentClipping(const gfx::Rect& clipping, const gfx::Size& content_size) OVERRIDE; virtual void AddFrameInfoCallback( @@ -199,6 +197,7 @@ class ContentViewCoreImpl : public ContentViewCore, void UpdateVSyncParameters(JNIEnv* env, jobject obj, jlong timebase_micros, jlong interval_micros); void OnVSync(JNIEnv* env, jobject /* obj */, jlong frame_time_micros); + jboolean OnAnimate(JNIEnv* env, jobject /* obj */, jlong frame_time_micros); jboolean PopulateBitmapFromCompositor(JNIEnv* env, jobject obj, jobject jbitmap); @@ -296,6 +295,7 @@ class ContentViewCoreImpl : public ContentViewCore, void AttachLayer(scoped_refptr<cc::Layer> layer); void RemoveLayer(scoped_refptr<cc::Layer> layer); void SetVSyncNotificationEnabled(bool enabled); + void SetNeedsAnimate(); private: enum InputEventVSyncStatus { diff --git a/content/browser/android/edge_effect.cc b/content/browser/android/edge_effect.cc new file mode 100644 index 0000000000..a9d493c2ac --- /dev/null +++ b/content/browser/android/edge_effect.cc @@ -0,0 +1,370 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/android/edge_effect.h" + +#include "cc/layers/layer.h" +#include "ui/gfx/screen.h" + +namespace content { + +namespace { + +enum State { + STATE_IDLE = 0, + STATE_PULL, + STATE_ABSORB, + STATE_RECEDE, + STATE_PULL_DECAY +}; + +// Time it will take the effect to fully recede in ms +const int kRecedeTime = 1000; + +// Time it will take before a pulled glow begins receding in ms +const int kPullTime = 167; + +// Time it will take in ms for a pulled glow to decay before release +const int kPullDecayTime = 1000; + +const float kMaxAlpha = 1.f; +const float kHeldEdgeScaleY = .5f; + +const float kMaxGlowHeight = 4.f; + +// Note: The Android version computes the aspect ratio from the source texture; +// because we use rescaled images, this is precomputed from the original Android +// textures. +const float kGlowImageAspectRatioInverse = 0.25f; + +const float kPullGlowBegin = 1.f; +const float kPullEdgeBegin = 0.6f; + +// Minimum velocity that will be absorbed +const float kMinVelocity = 100.f; + +const float kEpsilon = 0.001f; + +// How much dragging should effect the height of the edge image. +// Number determined by user testing. +const int kPullDistanceEdgeFactor = 7; + +// How much dragging should effect the height of the glow image. +// Number determined by user testing. +const int kPullDistanceGlowFactor = 7; +const float kPullDistanceAlphaGlowFactor = 1.1f; + +const int kVelocityEdgeFactor = 8; +const int kVelocityGlowFactor = 16; + +template <typename T> +T Lerp(T a, T b, T t) { + return a + (b - a) * t; +} + +template <typename T> +T Clamp(T value, T low, T high) { + return value < low ? low : (value > high ? high : value); +} + +template <typename T> +T Damp(T input, T factor) { + T result; + if (factor == 1) { + result = 1 - (1 - input) * (1 - input); + } else { + result = 1 - std::pow(1 - input, 2 * factor); + } + return result; +} + +gfx::Transform ComputeTransform(EdgeEffect::Edge edge, + gfx::SizeF size, int height) { + switch (edge) { + default: + case EdgeEffect::EDGE_TOP: + return gfx::Transform(1, 0, 0, 1, 0, 0); + case EdgeEffect::EDGE_LEFT: + return gfx::Transform(0, 1, -1, 0, + (-size.width() + height) / 2 , + (size.width() - height) / 2); + case EdgeEffect::EDGE_BOTTOM: + return gfx::Transform(-1, 0, 0, -1, 0, size.height() - height); + case EdgeEffect::EDGE_RIGHT: + return gfx::Transform(0, -1, 1, 0, + (-size.width() - height) / 2 + size.height(), + (size.width() - height) / 2); + }; +} + +void DisableLayer(cc::Layer* layer) { + DCHECK(layer); + layer->SetIsDrawable(false); + layer->SetTransform(gfx::Transform()); + layer->SetOpacity(1.f); +} + +void UpdateLayer(cc::Layer* layer, + EdgeEffect::Edge edge, + gfx::SizeF size, + int height, + float opacity) { + DCHECK(layer); + layer->SetIsDrawable(true); + layer->SetTransform(ComputeTransform(edge, size, height)); + layer->SetBounds(gfx::Size(size.width(), height)); + layer->SetOpacity(Clamp(opacity, 0.f, 1.f)); +} + +} // namespace + +EdgeEffect::EdgeEffect(scoped_refptr<cc::Layer> edge, + scoped_refptr<cc::Layer> glow) + : edge_(edge) + , glow_(glow) + , edge_alpha_(0) + , edge_scale_y_(0) + , glow_alpha_(0) + , glow_scale_y_(0) + , edge_alpha_start_(0) + , edge_alpha_finish_(0) + , edge_scale_y_start_(0) + , edge_scale_y_finish_(0) + , glow_alpha_start_(0) + , glow_alpha_finish_(0) + , glow_scale_y_start_(0) + , glow_scale_y_finish_(0) + , state_(STATE_IDLE) + , pull_distance_(0) + , dpi_scale_(1) { + // Prevent the provided layers from drawing until the effect is activated. + DisableLayer(edge_); + DisableLayer(glow_); + + dpi_scale_ = + gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().device_scale_factor(); +} + +EdgeEffect::~EdgeEffect() { } + +bool EdgeEffect::IsFinished() const { + return state_ == STATE_IDLE; +} + +void EdgeEffect::Finish() { + DisableLayer(edge_); + DisableLayer(glow_); + pull_distance_ = 0; + state_ = STATE_IDLE; +} + +void EdgeEffect::Pull(base::TimeTicks current_time, float delta_distance) { + if (state_ == STATE_PULL_DECAY && current_time - start_time_ < duration_) { + return; + } + if (state_ != STATE_PULL) { + glow_scale_y_ = kPullGlowBegin; + } + state_ = STATE_PULL; + + start_time_ = current_time; + duration_ = base::TimeDelta::FromMilliseconds(kPullTime); + + delta_distance *= dpi_scale_; + float abs_delta_distance = std::abs(delta_distance); + pull_distance_ += delta_distance; + float distance = std::abs(pull_distance_); + + edge_alpha_ = edge_alpha_start_ = Clamp(distance, kPullEdgeBegin, kMaxAlpha); + edge_scale_y_ = edge_scale_y_start_ + = Clamp(distance * kPullDistanceEdgeFactor, kHeldEdgeScaleY, 1.f); + + glow_alpha_ = glow_alpha_start_ = + std::min(kMaxAlpha, + glow_alpha_ + abs_delta_distance * kPullDistanceAlphaGlowFactor); + + float glow_change = abs_delta_distance; + if (delta_distance > 0 && pull_distance_ < 0) + glow_change = -glow_change; + if (pull_distance_ == 0) + glow_scale_y_ = 0; + + // Do not allow glow to get larger than kMaxGlowHeight. + glow_scale_y_ = glow_scale_y_start_ = + Clamp(glow_scale_y_ + glow_change * kPullDistanceGlowFactor, + 0.f, kMaxGlowHeight); + + edge_alpha_finish_ = edge_alpha_; + edge_scale_y_finish_ = edge_scale_y_; + glow_alpha_finish_ = glow_alpha_; + glow_scale_y_finish_ = glow_scale_y_; +} + +void EdgeEffect::Release(base::TimeTicks current_time) { + pull_distance_ = 0; + + if (state_ != STATE_PULL && state_ != STATE_PULL_DECAY) + return; + + state_ = STATE_RECEDE; + edge_alpha_start_ = edge_alpha_; + edge_scale_y_start_ = edge_scale_y_; + glow_alpha_start_ = glow_alpha_; + glow_scale_y_start_ = glow_scale_y_; + + edge_alpha_finish_ = 0.f; + edge_scale_y_finish_ = 0.f; + glow_alpha_finish_ = 0.f; + glow_scale_y_finish_ = 0.f; + + start_time_ = current_time; + duration_ = base::TimeDelta::FromMilliseconds(kRecedeTime); +} + +void EdgeEffect::Absorb(base::TimeTicks current_time, float velocity) { + state_ = STATE_ABSORB; + velocity = dpi_scale_ * std::max(kMinVelocity, std::abs(velocity)); + + start_time_ = current_time; + // This should never be less than 1 millisecond. + duration_ = base::TimeDelta::FromMilliseconds(0.1f + (velocity * 0.03f)); + + // The edge should always be at least partially visible, regardless + // of velocity. + edge_alpha_start_ = 0.f; + edge_scale_y_ = edge_scale_y_start_ = 0.f; + // The glow depends more on the velocity, and therefore starts out + // nearly invisible. + glow_alpha_start_ = 0.5f; + glow_scale_y_start_ = 0.f; + + // Factor the velocity by 8. Testing on device shows this works best to + // reflect the strength of the user's scrolling. + edge_alpha_finish_ = Clamp(velocity * kVelocityEdgeFactor, 0.f, 1.f); + // Edge should never get larger than the size of its asset. + edge_scale_y_finish_ = Clamp(velocity * kVelocityEdgeFactor, + kHeldEdgeScaleY, 1.f); + + // Growth for the size of the glow should be quadratic to properly + // respond + // to a user's scrolling speed. The faster the scrolling speed, the more + // intense the effect should be for both the size and the saturation. + glow_scale_y_finish_ = + std::min(0.025f + (velocity * (velocity / 100) * 0.00015f), 1.75f); + // Alpha should change for the glow as well as size. + glow_alpha_finish_ = + Clamp(glow_alpha_start_, + velocity * kVelocityGlowFactor * .00001f, kMaxAlpha); +} + +bool EdgeEffect::Update(base::TimeTicks current_time) { + if (IsFinished()) + return false; + + const double dt = (current_time - start_time_).InMilliseconds(); + const double t = std::min(dt / duration_.InMilliseconds(), 1.); + const float interp = static_cast<float>(Damp(t, 1.)); + + edge_alpha_ = Lerp(edge_alpha_start_, edge_alpha_finish_, interp); + edge_scale_y_ = Lerp(edge_scale_y_start_, edge_scale_y_finish_, interp); + glow_alpha_ = Lerp(glow_alpha_start_, glow_alpha_finish_, interp); + glow_scale_y_ = Lerp(glow_scale_y_start_, glow_scale_y_finish_, interp); + + if (t >= 1.f - kEpsilon) { + switch (state_) { + case STATE_ABSORB: + state_ = STATE_RECEDE; + start_time_ = current_time; + duration_ = base::TimeDelta::FromMilliseconds(kRecedeTime); + + edge_alpha_start_ = edge_alpha_; + edge_scale_y_start_ = edge_scale_y_; + glow_alpha_start_ = glow_alpha_; + glow_scale_y_start_ = glow_scale_y_; + + // After absorb, the glow and edge should fade to nothing. + edge_alpha_finish_ = 0.f; + edge_scale_y_finish_ = 0.f; + glow_alpha_finish_ = 0.f; + glow_scale_y_finish_ = 0.f; + break; + case STATE_PULL: + state_ = STATE_PULL_DECAY; + start_time_ = current_time; + duration_ = base::TimeDelta::FromMilliseconds(kPullDecayTime); + + edge_alpha_start_ = edge_alpha_; + edge_scale_y_start_ = edge_scale_y_; + glow_alpha_start_ = glow_alpha_; + glow_scale_y_start_ = glow_scale_y_; + + // After pull, the glow and edge should fade to nothing. + edge_alpha_finish_ = 0.f; + edge_scale_y_finish_ = 0.f; + glow_alpha_finish_ = 0.f; + glow_scale_y_finish_ = 0.f; + break; + case STATE_PULL_DECAY: + { + // When receding, we want edge to decrease more slowly + // than the glow. + float factor = glow_scale_y_finish_ != 0 ? + 1 / (glow_scale_y_finish_ * glow_scale_y_finish_) : + std::numeric_limits<float>::max(); + edge_scale_y_ = edge_scale_y_start_ + + (edge_scale_y_finish_ - edge_scale_y_start_) * interp * factor; + state_ = STATE_RECEDE; + } + break; + case STATE_RECEDE: + Finish(); + break; + default: + break; + } + } + + if (state_ == STATE_RECEDE && glow_scale_y_ <= 0 && edge_scale_y_ <= 0) + Finish(); + + return !IsFinished(); +} + +void EdgeEffect::ApplyToLayers(gfx::SizeF size, Edge edge) { + if (IsFinished()) + return; + + // An empty effect size, while meaningless, is also relatively harmless, and + // will simply prevent any drawing of the layers. + if (size.IsEmpty()) { + DisableLayer(edge_); + DisableLayer(glow_); + return; + } + + float dummy_scale_x, dummy_scale_y; + + // Glow + gfx::Size glow_image_bounds; + glow_->CalculateContentsScale(1.f, 1.f, 1.f, false, + &dummy_scale_x, &dummy_scale_y, + &glow_image_bounds); + const int glow_height = glow_image_bounds.height(); + const int glow_bottom = static_cast<int>(std::min( + glow_height * glow_scale_y_ * kGlowImageAspectRatioInverse * 0.6f, + glow_height * kMaxGlowHeight) * dpi_scale_ + 0.5f); + UpdateLayer(glow_, edge, size, glow_bottom, glow_alpha_); + + // Edge + gfx::Size edge_image_bounds; + edge_->CalculateContentsScale(1.f, 1.f, 1.f, false, + &dummy_scale_x, &dummy_scale_y, + &edge_image_bounds); + const int edge_height = edge_image_bounds.height(); + const int edge_bottom = static_cast<int>( + edge_height * edge_scale_y_ * dpi_scale_); + UpdateLayer(edge_, edge, size, edge_bottom, edge_alpha_); +} + +} // namespace content diff --git a/content/browser/android/edge_effect.h b/content/browser/android/edge_effect.h new file mode 100644 index 0000000000..b512195f8e --- /dev/null +++ b/content/browser/android/edge_effect.h @@ -0,0 +1,89 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_ANDROID_EDGE_EFFECT_H_ +#define CONTENT_BROWSER_ANDROID_EDGE_EFFECT_H_ + +#include "base/basictypes.h" +#include "base/memory/ref_counted.h" +#include "base/time.h" +#include "ui/gfx/size_f.h" + +namespace cc { +class Layer; +} + +namespace content { + +/* |EdgeEffect| mirrors its Android counterpart, EdgeEffect.java. + * The primary difference is ownership; the Android version manages render + * resources directly, while this version simply applies the effect to + * existing resources. Conscious tradeoffs were made to align this as closely + * as possible with the original Android java version. + */ +class EdgeEffect { +public: + enum Edge { + EDGE_TOP = 0, + EDGE_LEFT, + EDGE_BOTTOM, + EDGE_RIGHT, + EDGE_COUNT + }; + + EdgeEffect(scoped_refptr<cc::Layer> edge, scoped_refptr<cc::Layer> glow); + ~EdgeEffect(); + + void Pull(base::TimeTicks current_time, float delta_distance); + void Absorb(base::TimeTicks current_time, float velocity); + bool Update(base::TimeTicks current_time); + void Release(base::TimeTicks current_time); + + void Finish(); + bool IsFinished() const; + + void ApplyToLayers(gfx::SizeF size, Edge edge); + +private: + + enum State { + STATE_IDLE = 0, + STATE_PULL, + STATE_ABSORB, + STATE_RECEDE, + STATE_PULL_DECAY + }; + + scoped_refptr<cc::Layer> edge_; + scoped_refptr<cc::Layer> glow_; + + float edge_alpha_; + float edge_scale_y_; + float glow_alpha_; + float glow_scale_y_; + + float edge_alpha_start_; + float edge_alpha_finish_; + float edge_scale_y_start_; + float edge_scale_y_finish_; + float glow_alpha_start_; + float glow_alpha_finish_; + float glow_scale_y_start_; + float glow_scale_y_finish_; + + base::TimeTicks start_time_; + base::TimeDelta duration_; + + State state_; + + float pull_distance_; + + float dpi_scale_; + + DISALLOW_COPY_AND_ASSIGN(EdgeEffect); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_ANDROID_EDGE_EFFECT_H_ diff --git a/content/browser/android/media_player_manager_impl.cc b/content/browser/android/media_player_manager_impl.cc index 2fe672d0de..7a9a94e392 100644 --- a/content/browser/android/media_player_manager_impl.cc +++ b/content/browser/android/media_player_manager_impl.cc @@ -4,10 +4,9 @@ #include "content/browser/android/media_player_manager_impl.h" -#include "base/bind.h" #include "content/browser/android/media_resource_getter_impl.h" #include "content/browser/web_contents/web_contents_view_android.h" -#include "content/common/media/media_player_messages.h" +#include "content/common/media/media_player_messages_android.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/render_view_host.h" @@ -19,6 +18,26 @@ using media::MediaPlayerAndroid; // attempting to release inactive media players. static const int kMediaPlayerThreshold = 1; +namespace media { + +static MediaPlayerManager::FactoryFunction g_factory_function = NULL; + +// static +void MediaPlayerManager::RegisterFactoryFunction( + FactoryFunction factory_function) { + g_factory_function = factory_function; +} + +// static +media::MediaPlayerManager* MediaPlayerManager::Create( + content::RenderViewHost* render_view_host) { + if (g_factory_function) + return g_factory_function(render_view_host); + return new content::MediaPlayerManagerImpl(render_view_host); +} + +} // namespace media + namespace content { MediaPlayerManagerImpl::MediaPlayerManagerImpl( @@ -45,13 +64,15 @@ bool MediaPlayerManagerImpl::OnMessageReceived(const IPC::Message& msg) { IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_DestroyMediaPlayer, OnDestroyPlayer) IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_DestroyAllMediaPlayers, DestroyAllMediaPlayers) -#if defined(GOOGLE_TV) - IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_NotifyExternalSurface, - OnNotifyExternalSurface) IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_DemuxerReady, OnDemuxerReady) IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_ReadFromDemuxerAck, OnReadFromDemuxerAck) + IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_MediaSeekRequestAck, + OnMediaSeekRequestAck) +#if defined(GOOGLE_TV) + IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_NotifyExternalSurface, + OnNotifyExternalSurface) #endif IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() @@ -119,26 +140,7 @@ void MediaPlayerManagerImpl::OnInitialize( RenderProcessHost* host = render_view_host()->GetProcess(); players_.push_back(media::MediaPlayerAndroid::Create( player_id, url, is_media_source, first_party_for_cookies, - host->GetBrowserContext()->IsOffTheRecord(), this, -#if defined(GOOGLE_TV) - base::Bind(&MediaPlayerManagerImpl::OnReadFromDemuxer, - base::Unretained(this)), -#endif - base::Bind(&MediaPlayerManagerImpl::OnError, base::Unretained(this)), - base::Bind(&MediaPlayerManagerImpl::OnVideoSizeChanged, - base::Unretained(this)), - base::Bind(&MediaPlayerManagerImpl::OnBufferingUpdate, - base::Unretained(this)), - base::Bind(&MediaPlayerManagerImpl::OnMediaMetadataChanged, - base::Unretained(this)), - base::Bind(&MediaPlayerManagerImpl::OnPlaybackComplete, - base::Unretained(this)), - base::Bind(&MediaPlayerManagerImpl::OnSeekComplete, - base::Unretained(this)), - base::Bind(&MediaPlayerManagerImpl::OnTimeUpdate, - base::Unretained(this)), - base::Bind(&MediaPlayerManagerImpl::OnMediaInterrupted, - base::Unretained(this)))); + host->GetBrowserContext()->IsOffTheRecord(), this)); } media::MediaResourceGetter* MediaPlayerManagerImpl::GetMediaResourceGetter() { @@ -218,6 +220,14 @@ void MediaPlayerManagerImpl::DestroyAllMediaPlayers() { } } +void MediaPlayerManagerImpl::OnDemuxerReady( + int player_id, + const media::MediaPlayerHostMsg_DemuxerReady_Params& params) { + MediaPlayerAndroid* player = GetPlayer(player_id); + if (player) + player->DemuxerReady(params); +} + #if defined(GOOGLE_TV) void MediaPlayerManagerImpl::AttachExternalVideoSurface(int player_id, jobject surface) { @@ -243,13 +253,7 @@ void MediaPlayerManagerImpl::OnNotifyExternalSurface( view->NotifyExternalSurface(player_id, is_request, rect); } -void MediaPlayerManagerImpl::OnDemuxerReady( - int player_id, - const media::MediaPlayerHostMsg_DemuxerReady_Params& params) { - MediaPlayerAndroid* player = GetPlayer(player_id); - if (player) - player->DemuxerReady(params); -} +#endif void MediaPlayerManagerImpl::OnReadFromDemuxerAck( int player_id, @@ -258,7 +262,12 @@ void MediaPlayerManagerImpl::OnReadFromDemuxerAck( if (player) player->ReadFromDemuxerAck(params); } -#endif + +void MediaPlayerManagerImpl::OnMediaSeekRequestAck(int player_id) { + MediaPlayerAndroid* player = GetPlayer(player_id); + if (player) + player->OnSeekRequestAck(); +} MediaPlayerAndroid* MediaPlayerManagerImpl::GetPlayer(int player_id) { for (ScopedVector<MediaPlayerAndroid>::iterator it = players_.begin(); @@ -303,11 +312,22 @@ void MediaPlayerManagerImpl::OnBufferingUpdate( } void MediaPlayerManagerImpl::OnSeekComplete(int player_id, - base::TimeDelta current_time) { + base::TimeDelta current_time) { Send(new MediaPlayerMsg_MediaSeekCompleted( routing_id(), player_id, current_time)); } +void MediaPlayerManagerImpl::OnMediaSeekRequest( + int player_id, base::TimeDelta time_to_seek, bool request_surface) { + bool request_texture_peer = request_surface; + if (request_surface && player_id == fullscreen_player_id_) { + video_view_.CreateContentVideoView(); + request_texture_peer = false; + } + Send(new MediaPlayerMsg_MediaSeekRequest( + routing_id(), player_id, time_to_seek, request_texture_peer)); +} + void MediaPlayerManagerImpl::OnError(int player_id, int error) { Send(new MediaPlayerMsg_MediaError(routing_id(), player_id, error)); if (fullscreen_player_id_ != -1) @@ -328,13 +348,11 @@ void MediaPlayerManagerImpl::OnTimeUpdate(int player_id, routing_id(), player_id, current_time)); } -#if defined(GOOGLE_TV) void MediaPlayerManagerImpl::OnReadFromDemuxer( int player_id, media::DemuxerStream::Type type, bool seek_done) { Send(new MediaPlayerMsg_ReadFromDemuxer( routing_id(), player_id, type, seek_done)); } -#endif void MediaPlayerManagerImpl::RequestMediaResources( MediaPlayerAndroid* player) { diff --git a/content/browser/android/media_player_manager_impl.h b/content/browser/android/media_player_manager_impl.h index 61993b4b18..d1c9bb26f2 100644 --- a/content/browser/android/media_player_manager_impl.h +++ b/content/browser/android/media_player_manager_impl.h @@ -14,9 +14,7 @@ #include "content/browser/android/content_video_view.h" #include "content/public/browser/render_view_host_observer.h" #include "googleurl/src/gurl.h" -#if defined(GOOGLE_TV) #include "media/base/android/demuxer_stream_player_params.h" -#endif #include "media/base/android/media_player_android.h" #include "media/base/android/media_player_manager.h" #include "ui/gfx/rect_f.h" @@ -34,8 +32,6 @@ class MediaPlayerManagerImpl : public RenderViewHostObserver, public media::MediaPlayerManager { public: - // Create a MediaPlayerManagerImpl object for the |render_view_host|. - explicit MediaPlayerManagerImpl(RenderViewHost* render_view_host); virtual ~MediaPlayerManagerImpl(); // RenderViewHostObserver overrides. @@ -48,43 +44,50 @@ class MediaPlayerManagerImpl void ExitFullscreen(bool release_media_player); void SetVideoSurface(jobject surface); - // An internal method that checks for current time routinely and generates - // time update events. - void OnTimeUpdate(int player_id, base::TimeDelta current_time); - - // Callbacks needed by media::MediaPlayerAndroid. - void OnMediaMetadataChanged(int player_id, base::TimeDelta duration, - int width, int height, bool success); - void OnPlaybackComplete(int player_id); - void OnMediaInterrupted(int player_id); - void OnBufferingUpdate(int player_id, int percentage); - void OnSeekComplete(int player_id, base::TimeDelta current_time); - void OnError(int player_id, int error); - void OnVideoSizeChanged(int player_id, int width, int height); - -#if defined(GOOGLE_TV) - // Callbacks needed by media::DemuxerStreamPlayer. - void OnReadFromDemuxer( - int player_id, media::DemuxerStream::Type type, bool seek_done); -#endif - // media::MediaPlayerManager overrides. + virtual void OnTimeUpdate( + int player_id, base::TimeDelta current_time) OVERRIDE; + virtual void OnMediaMetadataChanged( + int player_id, + base::TimeDelta duration, + int width, + int height, + bool success) OVERRIDE; + virtual void OnPlaybackComplete(int player_id) OVERRIDE; + virtual void OnMediaInterrupted(int player_id) OVERRIDE; + virtual void OnBufferingUpdate(int player_id, int percentage) OVERRIDE; + virtual void OnSeekComplete( + int player_id, base::TimeDelta current_time) OVERRIDE; + virtual void OnError(int player_id, int error) OVERRIDE; + virtual void OnVideoSizeChanged( + int player_id, int width, int height) OVERRIDE; + virtual void OnReadFromDemuxer( + int player_id, + media::DemuxerStream::Type type, + bool seek_done) OVERRIDE; virtual void RequestMediaResources( media::MediaPlayerAndroid* player) OVERRIDE; virtual void ReleaseMediaResources( media::MediaPlayerAndroid* player) OVERRIDE; virtual media::MediaResourceGetter* GetMediaResourceGetter() OVERRIDE; - - // Release all the players managed by this object. - void DestroyAllMediaPlayers(); + virtual media::MediaPlayerAndroid* GetFullscreenPlayer() OVERRIDE; + virtual media::MediaPlayerAndroid* GetPlayer(int player_id) OVERRIDE; + virtual void DestroyAllMediaPlayers() OVERRIDE; + virtual void OnMediaSeekRequest(int player_id, base::TimeDelta time_to_seek, + bool request_surface) OVERRIDE; #if defined(GOOGLE_TV) void AttachExternalVideoSurface(int player_id, jobject surface); void DetachExternalVideoSurface(int player_id); #endif - media::MediaPlayerAndroid* GetFullscreenPlayer(); - media::MediaPlayerAndroid* GetPlayer(int player_id); + protected: + friend MediaPlayerManager* MediaPlayerManager::Create( + content::RenderViewHost*); + + // The instance of this class is supposed to be created by either Create() + // method of MediaPlayerManager or the derived classes constructors. + explicit MediaPlayerManagerImpl(RenderViewHost* render_view_host); private: // Message handlers. @@ -98,15 +101,17 @@ class MediaPlayerManagerImpl void OnPause(int player_id); void OnReleaseResources(int player_id); void OnDestroyPlayer(int player_id); -#if defined(GOOGLE_TV) - void OnNotifyExternalSurface( - int player_id, bool is_request, const gfx::RectF& rect); void OnDemuxerReady( int player_id, const media::MediaPlayerHostMsg_DemuxerReady_Params& params); void OnReadFromDemuxerAck( int player_id, const media::MediaPlayerHostMsg_ReadFromDemuxerAck_Params& params); + void OnMediaSeekRequestAck(int player_id); + +#if defined(GOOGLE_TV) + void OnNotifyExternalSurface( + int player_id, bool is_request, const gfx::RectF& rect); #endif // An array of managed players. diff --git a/content/browser/android/overscroll_glow.cc b/content/browser/android/overscroll_glow.cc new file mode 100644 index 0000000000..39478f47be --- /dev/null +++ b/content/browser/android/overscroll_glow.cc @@ -0,0 +1,263 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/android/overscroll_glow.h" + +#include "base/lazy_instance.h" +#include "cc/layers/image_layer.h" +#include "content/browser/android/edge_effect.h" +#include "skia/ext/image_operations.h" +#include "ui/gfx/android/java_bitmap.h" + +using std::max; +using std::min; + +namespace content { + +namespace { + +const float kEpsilon = 1e-3f; + +SkBitmap CreateBitmap(const char* resource, gfx::Size size) { + SkBitmap bitmap = gfx::CreateSkBitmapFromResource(resource); + if (bitmap.isNull()) + return bitmap; + return skia::ImageOperations::Resize(bitmap, + skia::ImageOperations::RESIZE_GOOD, + size.width(), size.height()); +} + +class OverscrollResources { + public: + OverscrollResources() + : edge_bitmap_(CreateBitmap("android:drawable/overscroll_edge", + gfx::Size(256, 12))), + glow_bitmap_(CreateBitmap("android:drawable/overscroll_glow", + gfx::Size(128, 128))) { + } + + const SkBitmap& edge_bitmap() { return edge_bitmap_; } + const SkBitmap& glow_bitmap() { return glow_bitmap_; } + + private: + SkBitmap edge_bitmap_; + SkBitmap glow_bitmap_; + + DISALLOW_COPY_AND_ASSIGN(OverscrollResources); +}; + +base::LazyInstance<OverscrollResources> g_overscroll_resources = + LAZY_INSTANCE_INITIALIZER; + +scoped_refptr<cc::Layer> CreateImageLayer(const SkBitmap& bitmap) { + scoped_refptr<cc::ImageLayer> layer = cc::ImageLayer::Create(); + layer->SetBitmap(bitmap); + return layer; +} + +bool IsApproxZero(float value) { + return std::abs(value) < kEpsilon; +} + +bool IsApproxZero(gfx::Vector2dF vector) { + return IsApproxZero(vector.x()) && IsApproxZero(vector.y()); +} + +gfx::Vector2dF ZeroSmallComponents(gfx::Vector2dF vector) { + if (IsApproxZero(vector.x())) + vector.set_x(0); + if (IsApproxZero(vector.y())) + vector.set_y(0); + return vector; +} + +} // namespace + +scoped_ptr<OverscrollGlow> OverscrollGlow::Create() { + const SkBitmap& edge = g_overscroll_resources.Get().edge_bitmap(); + const SkBitmap& glow = g_overscroll_resources.Get().glow_bitmap(); + if (edge.isNull() || glow.isNull()) + return scoped_ptr<OverscrollGlow>(); + + return make_scoped_ptr(new OverscrollGlow(edge, glow)); +} + +OverscrollGlow::OverscrollGlow(const SkBitmap& edge, const SkBitmap& glow) + : horizontal_overscroll_enabled_(true), + vertical_overscroll_enabled_(true), + root_layer_(cc::Layer::Create()) { + for (size_t i = 0; i < EdgeEffect::EDGE_COUNT; ++i) { + scoped_refptr<cc::Layer> edge_layer = CreateImageLayer(edge); + scoped_refptr<cc::Layer> glow_layer = CreateImageLayer(glow); + root_layer_->AddChild(edge_layer); + root_layer_->AddChild(glow_layer); + edge_effects_[i] = make_scoped_ptr(new EdgeEffect(edge_layer, glow_layer)); + } +} + +OverscrollGlow::~OverscrollGlow() { + root_layer_->RemoveFromParent(); +} + +void OverscrollGlow::OnOverscrolled(base::TimeTicks current_time, + gfx::Vector2dF overscroll, + gfx::Vector2dF velocity) { + // The size of the glow determines the relative effect of the inputs; an + // empty-sized effect is effectively disabled. + if (size_.IsEmpty()) + return; + + if (!horizontal_overscroll_enabled_) { + overscroll.set_x(0); + velocity.set_x(0); + } + if (!vertical_overscroll_enabled_) { + overscroll.set_y(0); + velocity.set_y(0); + } + + // Ignore sufficiently small values that won't meaningfuly affect animation. + overscroll = ZeroSmallComponents(overscroll); + velocity = ZeroSmallComponents(velocity); + + if (overscroll.IsZero()) { + Release(current_time); + return; + } + + if (!velocity.IsZero()) { + // Release effects if scrolling has changed directions. + if (velocity.x() * old_velocity_.x() < 0) + Release(AXIS_X, current_time); + if (velocity.y() * old_velocity_.y() < 0) + Release(AXIS_Y, current_time); + + Absorb(current_time, velocity, overscroll, old_overscroll_); + } else { + // Release effects when overscroll accumulation violates monotonicity. + if (overscroll.x() * old_overscroll_.x() < 0 || + std::abs(overscroll.x()) < std::abs(old_overscroll_.x())) + Release(AXIS_X, current_time); + if (overscroll.y() * old_overscroll_.y() < 0 || + std::abs(overscroll.y()) < std::abs(old_overscroll_.y())) + Release(AXIS_Y, current_time); + + Pull(current_time, overscroll - old_overscroll_); + } + + old_velocity_ = velocity; + old_overscroll_ = overscroll; +} + +bool OverscrollGlow::Animate(base::TimeTicks current_time) { + if (!IsActive()) + return false; + + const gfx::SizeF sizes[EdgeEffect::EDGE_COUNT] = { + size_, gfx::SizeF(size_.height(), size_.width()), + size_, gfx::SizeF(size_.height(), size_.width()) + }; + + for (size_t i = 0; i < EdgeEffect::EDGE_COUNT; ++i) { + if (edge_effects_[i]->Update(current_time)) { + edge_effects_[i]->ApplyToLayers(sizes[i], + static_cast<EdgeEffect::Edge>(i)); + } + } + + return IsActive(); +} + +bool OverscrollGlow::IsActive() const { + for (size_t i = 0; i < EdgeEffect::EDGE_COUNT; ++i) { + if (!edge_effects_[i]->IsFinished()) + return true; + } + return false; +} + +void OverscrollGlow::Finish() { + for (size_t i = 0; i < EdgeEffect::EDGE_COUNT; ++i) + edge_effects_[i]->Finish(); +} + +void OverscrollGlow::Pull(base::TimeTicks current_time, + gfx::Vector2dF overscroll_delta) { + overscroll_delta = ZeroSmallComponents(overscroll_delta); + if (overscroll_delta.IsZero()) + return; + + gfx::Vector2dF overscroll_pull = gfx::ScaleVector2d(overscroll_delta, + 1.f / size_.width(), + 1.f / size_.height()); + float edge_overscroll_pull[EdgeEffect::EDGE_COUNT] = { + min(overscroll_pull.y(), 0.f), // Top + min(overscroll_pull.x(), 0.f), // Left + max(overscroll_pull.y(), 0.f), // Bottom + max(overscroll_pull.x(), 0.f) // Right + }; + + for (size_t i = 0; i < EdgeEffect::EDGE_COUNT; ++i) { + if (!edge_overscroll_pull[i]) + continue; + + edge_effects_[i]->Pull(current_time, std::abs(edge_overscroll_pull[i])); + GetOppositeEdge(i)->Release(current_time); + } +} + +void OverscrollGlow::Absorb(base::TimeTicks current_time, + gfx::Vector2dF velocity, + gfx::Vector2dF overscroll, + gfx::Vector2dF old_overscroll) { + if (overscroll.IsZero() || velocity.IsZero()) + return; + + // Only trigger on initial overscroll at a non-zero velocity + const float overscroll_velocities[EdgeEffect::EDGE_COUNT] = { + old_overscroll.y() >= 0 && overscroll.y() < 0 ? min(velocity.y(), 0.f) : 0, + old_overscroll.x() >= 0 && overscroll.x() < 0 ? min(velocity.x(), 0.f) : 0, + old_overscroll.y() <= 0 && overscroll.y() > 0 ? max(velocity.y(), 0.f) : 0, + old_overscroll.x() <= 0 && overscroll.x() > 0 ? max(velocity.x(), 0.f) : 0 + }; + + for (size_t i = 0; i < EdgeEffect::EDGE_COUNT; ++i) { + if (!overscroll_velocities[i]) + continue; + + edge_effects_[i]->Absorb(current_time, std::abs(overscroll_velocities[i])); + GetOppositeEdge(i)->Release(current_time); + } +} + +void OverscrollGlow::Release(base::TimeTicks current_time) { + for (size_t i = 0; i < EdgeEffect::EDGE_COUNT; ++i) { + edge_effects_[i]->Release(current_time); + } + old_overscroll_ = old_velocity_ = gfx::Vector2dF(); +} + +void OverscrollGlow::Release(Axis axis, base::TimeTicks current_time) { + switch (axis) { + case AXIS_X: + edge_effects_[EdgeEffect::EDGE_LEFT]->Release(current_time); + edge_effects_[EdgeEffect::EDGE_RIGHT]->Release(current_time); + old_overscroll_.set_x(0); + old_velocity_.set_x(0); + break; + case AXIS_Y: + edge_effects_[EdgeEffect::EDGE_TOP]->Release(current_time); + edge_effects_[EdgeEffect::EDGE_BOTTOM]->Release(current_time); + old_overscroll_.set_y(0); + old_velocity_.set_y(0); + break; + }; +} + +EdgeEffect* OverscrollGlow::GetOppositeEdge(int edge_index) { + return edge_effects_[(edge_index + 2) % EdgeEffect::EDGE_COUNT].get(); +} + +} // namespace content + diff --git a/content/browser/android/overscroll_glow.h b/content/browser/android/overscroll_glow.h new file mode 100644 index 0000000000..a0ca321ef2 --- /dev/null +++ b/content/browser/android/overscroll_glow.h @@ -0,0 +1,91 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_ANDROID_OVERSCROLL_GLOW_H_ +#define CONTENT_BROWSER_ANDROID_OVERSCROLL_GLOW_H_ + +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" +#include "base/time.h" +#include "content/browser/android/edge_effect.h" +#include "ui/gfx/size_f.h" +#include "ui/gfx/vector2d_f.h" + +class SkBitmap; + +namespace cc { +class Layer; +} + +namespace content { + +/* |OverscrollGlow| mirrors its Android counterpart, EdgeEffect.java. + * Conscious tradeoffs were made to align this as closely as possible with the + * original Android java version. + */ +class OverscrollGlow { + public: + static scoped_ptr<OverscrollGlow> Create(); + + ~OverscrollGlow(); + + void OnOverscrolled(base::TimeTicks current_time, + gfx::Vector2dF overscroll, + gfx::Vector2dF velocity); + // Returns true if the effect still needs animation ticks. + bool Animate(base::TimeTicks current_time); + void Finish(); + + // Returns true if the effect needs animation ticks. + bool IsActive() const; + + // The root layer of the effect (not necessarily of the tree). + scoped_refptr<cc::Layer> root_layer() const { + return root_layer_; + } + + void set_horizontal_overscroll_enabled(bool enabled) { + horizontal_overscroll_enabled_ = enabled; + } + void set_vertical_overscroll_enabled(bool enabled) { + vertical_overscroll_enabled_ = enabled; + } + + void set_size(gfx::SizeF size) { + size_ = size; + } + + private: + enum Axis { AXIS_X, AXIS_Y }; + + OverscrollGlow(const SkBitmap& edge, const SkBitmap& glow); + + void Pull(base::TimeTicks current_time, + gfx::Vector2dF added_overscroll); + void Absorb(base::TimeTicks current_time, + gfx::Vector2dF velocity, + gfx::Vector2dF overscroll, + gfx::Vector2dF old_overscroll); + + void Release(base::TimeTicks current_time); + void Release(Axis axis, base::TimeTicks current_time); + + EdgeEffect* GetOppositeEdge(int edge_index); + + scoped_ptr<EdgeEffect> edge_effects_[EdgeEffect::EDGE_COUNT]; + + gfx::SizeF size_; + gfx::Vector2dF old_overscroll_; + gfx::Vector2dF old_velocity_; + bool horizontal_overscroll_enabled_; + bool vertical_overscroll_enabled_; + + scoped_refptr<cc::Layer> root_layer_; + + DISALLOW_COPY_AND_ASSIGN(OverscrollGlow); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_ANDROID_SCROLL_GLOW_H_ diff --git a/content/browser/android/surface_texture_peer_browser_impl.cc b/content/browser/android/surface_texture_peer_browser_impl.cc index fecc31797d..ee3e00aa0a 100644 --- a/content/browser/android/surface_texture_peer_browser_impl.cc +++ b/content/browser/android/surface_texture_peer_browser_impl.cc @@ -4,11 +4,11 @@ #include "content/browser/android/surface_texture_peer_browser_impl.h" -#include "content/browser/android/media_player_manager_impl.h" #include "content/browser/renderer_host/render_view_host_impl.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/render_process_host.h" #include "media/base/android/media_player_android.h" +#include "media/base/android/media_player_manager.h" #include "ui/gl/android/scoped_java_surface.h" namespace content { diff --git a/content/browser/android/sync_input_event_filter.cc b/content/browser/android/sync_input_event_filter.cc index f1a2e9974f..fb252c360c 100644 --- a/content/browser/android/sync_input_event_filter.cc +++ b/content/browser/android/sync_input_event_filter.cc @@ -4,77 +4,12 @@ #include "base/debug/trace_event.h" #include "content/browser/android/sync_input_event_filter.h" -#include "third_party/WebKit/Source/WebKit/chromium/public/WebCompositorInputHandler.h" -#include "third_party/WebKit/Source/WebKit/chromium/public/WebCompositorInputHandlerClient.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" using WebKit::WebInputEvent; namespace content { -class SyncInputEventFilter::InputHandlerWrapper - : public WebKit::WebCompositorInputHandlerClient { - public: - InputHandlerWrapper(SyncInputEventFilter* event_filter, - WebKit::WebCompositorInputHandler* input_handler) - : event_result_(INPUT_EVENT_ACK_STATE_UNKNOWN), - event_filter_(event_filter), - input_handler_(input_handler) { - input_handler_->setClient(this); - } - - virtual ~InputHandlerWrapper() { - input_handler_->setClient(NULL); - } - - InputEventAckState HandleInputEvent( - const WebKit::WebInputEvent& input_event) { - - // Clear the result for the (unexpected) case that callbacks to - // did/didNotHandleInputEvent are not made synchronously. - event_result_ = INPUT_EVENT_ACK_STATE_UNKNOWN; - - // It is expected that input_handler_ makes an appropriate synchronous - // callback to did/didNotHandleInputEvent. event_result_ is then assigned in - // those callbacks. - input_handler_->handleInputEvent(input_event); - - DCHECK(event_result_ != INPUT_EVENT_ACK_STATE_UNKNOWN); - - return event_result_; - } - - WebKit::WebCompositorInputHandler* input_handler() const { - return input_handler_; - } - - // WebCompositorInputHandlerClient methods: - - virtual void willShutdown() { - event_filter_->ClearInputHandler(); - } - - virtual void didHandleInputEvent() { - event_result_ = INPUT_EVENT_ACK_STATE_CONSUMED; - } - - virtual void didNotHandleInputEvent(bool send_to_widget) { - event_result_ = send_to_widget ? INPUT_EVENT_ACK_STATE_NOT_CONSUMED - : INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS; - } - - private: - // This acts as a temporary result, storing the result of the - // did/didNotHandleInputEvent callbacks. We use it to avoid creating a - // closure or reference to a stack variable. - InputEventAckState event_result_; - - SyncInputEventFilter* event_filter_; - WebKit::WebCompositorInputHandler* input_handler_; - - DISALLOW_COPY_AND_ASSIGN(InputHandlerWrapper); -}; - //------------------------------------------------------------------------------ SyncInputEventFilter::SyncInputEventFilter() { @@ -86,37 +21,11 @@ SyncInputEventFilter::~SyncInputEventFilter() { InputEventAckState SyncInputEventFilter::HandleInputEvent( const WebInputEvent& event) { - if (!input_handler_) - return INPUT_EVENT_ACK_STATE_NOT_CONSUMED; - - return input_handler_->HandleInputEvent(event); -} - -void SyncInputEventFilter::SetInputHandler( - WebKit::WebCompositorInputHandler* new_input_handler) { - DCHECK(thread_checker_.CalledOnValidThread()); - - if (!new_input_handler) { - return; - } - - if (input_handler_) { - // It's valid to call SetInputHandler() with the same input_handler many - // times, but it's not valid to change the input_handler once it's been set. - DCHECK_EQ(input_handler_->input_handler(), new_input_handler); - return; - } - - TRACE_EVENT0("SyncInputEventFilter::SetInputHandler", - "SettingHandler"); - input_handler_.reset(new InputHandlerWrapper(this, new_input_handler)); + return INPUT_EVENT_ACK_STATE_NOT_CONSUMED; } void SyncInputEventFilter::ClearInputHandler() { DCHECK(thread_checker_.CalledOnValidThread()); - TRACE_EVENT0("SyncInputEventFilter::ClearInputHandler", - "ClearingHandler"); - input_handler_.reset(); } } // namespace content diff --git a/content/browser/android/sync_input_event_filter.h b/content/browser/android/sync_input_event_filter.h index dea75243c1..e2ce90b88a 100644 --- a/content/browser/android/sync_input_event_filter.h +++ b/content/browser/android/sync_input_event_filter.h @@ -10,7 +10,6 @@ #include "content/port/common/input_event_ack_state.h" namespace WebKit { -class WebCompositorInputHandler; class WebInputEvent; } @@ -26,16 +25,12 @@ class SyncInputEventFilter { ~SyncInputEventFilter(); InputEventAckState HandleInputEvent(const WebKit::WebInputEvent& input_event); - void SetInputHandler(WebKit::WebCompositorInputHandler* input_handler); void ClearInputHandler(); private: // Used to DCHECK that input_handler_ changes are made on the correct thread. base::ThreadChecker thread_checker_; - class InputHandlerWrapper; - scoped_ptr<InputHandlerWrapper> input_handler_; - DISALLOW_COPY_AND_ASSIGN(SyncInputEventFilter); }; diff --git a/content/browser/browser_child_process_host_impl.cc b/content/browser/browser_child_process_host_impl.cc index 6a2218fe2d..a4f339c68c 100644 --- a/content/browser/browser_child_process_host_impl.cc +++ b/content/browser/browser_child_process_host_impl.cc @@ -21,7 +21,6 @@ #include "content/browser/profiler_message_filter.h" #include "content/browser/tracing/trace_message_filter.h" #include "content/common/child_process_host_impl.h" -#include "content/common/plugin_messages.h" #include "content/public/browser/browser_child_process_host_delegate.h" #include "content/public/browser/browser_child_process_observer.h" #include "content/public/browser/browser_thread.h" diff --git a/content/browser/browser_context.cc b/content/browser/browser_context.cc index b32b58a2b5..c350d5941c 100644 --- a/content/browser/browser_context.cc +++ b/content/browser/browser_context.cc @@ -24,8 +24,8 @@ #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context_getter.h" #include "ui/base/clipboard/clipboard.h" -#include "webkit/database/database_tracker.h" -#include "webkit/fileapi/external_mount_points.h" +#include "webkit/browser/database/database_tracker.h" +#include "webkit/browser/fileapi/external_mount_points.h" #endif // !OS_IOS using base::UserDataAdapter; @@ -156,18 +156,18 @@ DownloadManager* BrowserContext::GetDownloadManager( if (!context->GetUserData(kDownloadManagerKeyName)) { ResourceDispatcherHostImpl* rdh = ResourceDispatcherHostImpl::Get(); DCHECK(rdh); - scoped_refptr<DownloadManager> download_manager = + DownloadManager* download_manager = new DownloadManagerImpl( GetContentClient()->browser()->GetNetLog(), context); context->SetUserData( kDownloadManagerKeyName, - new UserDataAdapter<DownloadManager>(download_manager)); + download_manager); download_manager->SetDelegate(context->GetDownloadManagerDelegate()); } - return UserDataAdapter<DownloadManager>::Get( - context, kDownloadManagerKeyName); + return static_cast<DownloadManager*>( + context->GetUserData(kDownloadManagerKeyName)); } // static diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc index 67ef5bddf3..a84b87d964 100644 --- a/content/browser/browser_main_loop.cc +++ b/content/browser/browser_main_loop.cc @@ -60,8 +60,6 @@ #include "base/android/jni_android.h" #include "content/browser/android/surface_texture_peer_browser_impl.h" #include "content/browser/device_orientation/data_fetcher_impl_android.h" -// TODO(epenner): Move thread priorities to base. (crbug.com/170549) -#include <sys/resource.h> #endif #if defined(OS_WIN) @@ -69,6 +67,7 @@ #include <commctrl.h> #include <shellapi.h> +#include "base/win/text_services_message_filter.h" #include "content/browser/system_message_window_win.h" #include "content/common/sandbox_win.h" #include "net/base/winsock_init.h" @@ -160,6 +159,9 @@ static void GLibLogHandler(const gchar* log_domain, } } else if (strstr(message, "Unable to retrieve the file info for")) { LOG(ERROR) << "GTK File code error: " << message; + } else if (strstr(message, "Could not find the icon") && + strstr(log_domain, "Gtk")) { + LOG(ERROR) << "GTK icon error: " << message; } else if (strstr(message, "Theme file for default has no") || strstr(message, "Theme directory") || strstr(message, "theme pixmap") || @@ -402,6 +404,17 @@ void BrowserMainLoop::MainMessageLoopStart() { #if defined(OS_WIN) system_message_window_.reset(new SystemMessageWindowWin); + + if (base::win::IsTSFAwareRequired()) { + // Create a TSF message filter for the message loop. MessageLoop takes + // ownership of the filter. + scoped_ptr<base::win::TextServicesMessageFilter> tsf_message_filter( + new base::win::TextServicesMessageFilter); + if (tsf_message_filter->Init()) { + MessageLoopForUI::current()->SetMessageFilter( + tsf_message_filter.PassAs<MessageLoopForUI::MessageFilter>()); + } + } #endif if (parts_) @@ -716,26 +729,15 @@ void BrowserMainLoop::InitializeMainThread() { new BrowserThreadImpl(BrowserThread::UI, base::MessageLoop::current())); } -#if defined(OS_ANDROID) -// TODO(epenner): Move thread priorities to base. (crbug.com/170549) -namespace { -void SetHighThreadPriority() { - int nice_value = -6; // High priority. - setpriority(PRIO_PROCESS, base::PlatformThread::CurrentId(), nice_value); -} -} -#endif - void BrowserMainLoop::BrowserThreadsStarted() { TRACE_EVENT0("startup", "BrowserMainLoop::BrowserThreadsStarted") #if defined(OS_ANDROID) -// TODO(epenner): Move thread priorities to base. (crbug.com/170549) - BrowserThread::PostTask(BrowserThread::UI, - FROM_HERE, - base::Bind(&SetHighThreadPriority)); - BrowserThread::PostTask(BrowserThread::IO, - FROM_HERE, - base::Bind(&SetHighThreadPriority)); + // Up the priority of anything that touches with display tasks + // (this thread is UI thread, and io_thread_ is for IPCs). + io_thread_->SetPriority(base::kThreadPriority_Display); + base::PlatformThread::SetThreadPriority( + base::PlatformThread::CurrentHandle(), + base::kThreadPriority_Display); #endif #if !defined(OS_IOS) diff --git a/content/browser/browser_plugin/browser_plugin_embedder.cc b/content/browser/browser_plugin/browser_plugin_embedder.cc index 12de8efe92..ba8b10a0d2 100644 --- a/content/browser/browser_plugin/browser_plugin_embedder.cc +++ b/content/browser/browser_plugin/browser_plugin_embedder.cc @@ -75,6 +75,10 @@ void BrowserPluginEmbedder::GetRenderViewHostAtPosition( ++next_get_render_view_request_id_; } +void BrowserPluginEmbedder::DidSendScreenRects(RenderWidgetHostImpl* rwh) { + GetBrowserPluginGuestManager()->DidSendScreenRects(web_contents(), rwh); +} + void BrowserPluginEmbedder::RenderViewGone(base::TerminationStatus status) { CleanUp(); } diff --git a/content/browser/browser_plugin/browser_plugin_embedder.h b/content/browser/browser_plugin/browser_plugin_embedder.h index 1b6c8b248a..3dbb3f3cd5 100644 --- a/content/browser/browser_plugin/browser_plugin_embedder.h +++ b/content/browser/browser_plugin/browser_plugin_embedder.h @@ -33,6 +33,7 @@ namespace content { class BrowserPluginGuest; class BrowserPluginGuestManager; class BrowserPluginHostFactory; +class RenderWidgetHostImpl; class WebContentsImpl; class CONTENT_EXPORT BrowserPluginEmbedder : public WebContentsObserver { @@ -49,6 +50,9 @@ class CONTENT_EXPORT BrowserPluginEmbedder : public WebContentsObserver { int y, const WebContents::GetRenderViewHostCallback& callback); + // Called when embedder's |rwh| has sent screen rects to renderer. + void DidSendScreenRects(RenderWidgetHostImpl* rwh); + // Overrides factory for testing. Default (NULL) value indicates regular // (non-test) environment. static void set_factory_for_testing(BrowserPluginHostFactory* factory) { diff --git a/content/browser/browser_plugin/browser_plugin_guest.cc b/content/browser/browser_plugin/browser_plugin_guest.cc index 9bd64d9e82..d1c6caa705 100644 --- a/content/browser/browser_plugin/browser_plugin_guest.cc +++ b/content/browser/browser_plugin/browser_plugin_guest.cc @@ -65,7 +65,9 @@ class BrowserPluginGuest::PermissionRequest { virtual void Respond(bool should_allow) = 0; virtual ~PermissionRequest() {} protected: - PermissionRequest() {} + PermissionRequest() { + RecordAction(UserMetricsAction("BrowserPlugin.Guest.PermissionRequest")); + } }; class BrowserPluginGuest::DownloadRequest : public PermissionRequest { @@ -354,6 +356,7 @@ bool BrowserPluginGuest::OnMessageReceivedFromEmbedder( IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_Stop, OnStop) IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_TerminateGuest, OnTerminateGuest) IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_UnlockMouse_ACK, OnUnlockMouseAck) + IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_UpdateGeometry, OnUpdateGeometry) IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_UpdateRect_ACK, OnUpdateRectACK) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() @@ -365,6 +368,8 @@ void BrowserPluginGuest::Initialize( const BrowserPluginHostMsg_Attach_Params& params) { focused_ = params.focused; guest_visible_ = params.visible; + guest_window_rect_ = params.resize_guest_params.view_rect; + if (!params.name.empty()) name_ = params.name; auto_size_enabled_ = params.auto_size_params.enable; @@ -470,6 +475,13 @@ void BrowserPluginGuest::UpdateVisibility() { OnSetVisibility(instance_id_, visible()); } +// screen. +gfx::Rect BrowserPluginGuest::ToGuestRect(const gfx::Rect& bounds) { + gfx::Rect guest_rect(bounds); + guest_rect.Offset(guest_window_rect_.OffsetFromOrigin()); + return guest_rect; +} + void BrowserPluginGuest::Observe(int type, const NotificationSource& source, const NotificationDetails& details) { @@ -665,7 +677,7 @@ void BrowserPluginGuest::SetDamageBuffer( DCHECK(*static_cast<unsigned int*>(damage_buffer_->memory()) == 0xdeadbeef); damage_buffer_sequence_id_ = params.damage_buffer_sequence_id; damage_buffer_size_ = params.damage_buffer_size; - damage_view_size_ = params.view_size; + damage_view_size_ = params.view_rect.size(); damage_buffer_scale_factor_ = params.scale_factor; } @@ -970,6 +982,7 @@ bool BrowserPluginGuest::ShouldForwardToBrowserPluginGuest( case BrowserPluginHostMsg_Stop::ID: case BrowserPluginHostMsg_TerminateGuest::ID: case BrowserPluginHostMsg_UnlockMouse_ACK::ID: + case BrowserPluginHostMsg_UpdateGeometry::ID: case BrowserPluginHostMsg_UpdateRect_ACK::ID: return true; default: @@ -1061,6 +1074,8 @@ void BrowserPluginGuest::Attach( new BrowserPluginMsg_Attach_ACK(instance_id_, ack_params)); SendQueuedMessages(); + + RecordAction(UserMetricsAction("BrowserPlugin.Guest.Attached")); } void BrowserPluginGuest::OnCompositorFrameACK( @@ -1247,16 +1262,16 @@ void BrowserPluginGuest::OnResizeGuest( // Invalid damage buffer means we are in HW compositing mode, // so just resize the WebContents and repaint if needed. if (!base::SharedMemory::IsHandleValid(params.damage_buffer_handle)) { - if (!params.view_size.IsEmpty()) - GetWebContents()->GetView()->SizeContents(params.view_size); + if (!params.view_rect.size().IsEmpty()) + GetWebContents()->GetView()->SizeContents(params.view_rect.size()); if (params.repaint) - Send(new ViewMsg_Repaint(routing_id(), params.view_size)); + Send(new ViewMsg_Repaint(routing_id(), params.view_rect.size())); return; } SetDamageBuffer(params); - GetWebContents()->GetView()->SizeContents(params.view_size); + GetWebContents()->GetView()->SizeContents(params.view_rect.size()); if (params.repaint) - Send(new ViewMsg_Repaint(routing_id(), params.view_size)); + Send(new ViewMsg_Repaint(routing_id(), params.view_rect.size())); } void BrowserPluginGuest::OnSetFocus(int instance_id, bool focused) { @@ -1300,7 +1315,7 @@ void BrowserPluginGuest::OnSetSize( Send(new ViewMsg_Repaint(routing_id(), max_auto_size_)); } else if (!auto_size_enabled_ && old_auto_size_enabled) { GetWebContents()->GetRenderViewHost()->DisableAutoResize( - resize_guest_params.view_size); + resize_guest_params.view_rect.size()); } OnResizeGuest(instance_id_, resize_guest_params); } @@ -1382,6 +1397,17 @@ void BrowserPluginGuest::OnUpdateRectACK( OnSetSize(instance_id_, auto_size_params, resize_guest_params); } +void BrowserPluginGuest::OnUpdateGeometry(int instance_id, + const gfx::Rect& view_rect) { + // The plugin has moved within the embedder without resizing or the + // embedder/container's view rect changing. + guest_window_rect_ = view_rect; + RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>( + GetWebContents()->GetRenderViewHost()); + if (rvh) + rvh->SendScreenRects(); +} + void BrowserPluginGuest::OnHasTouchEventHandlers(bool accept) { SendMessageToEmbedder( new BrowserPluginMsg_ShouldAcceptTouchEvents(instance_id(), accept)); @@ -1411,9 +1437,7 @@ void BrowserPluginGuest::OnShowPopup( void BrowserPluginGuest::OnShowWidget(int route_id, const gfx::Rect& initial_pos) { - gfx::Rect screen_pos(initial_pos); - screen_pos.Offset(guest_screen_rect_.OffsetFromOrigin()); - GetWebContents()->ShowCreatedWidget(route_id, screen_pos); + GetWebContents()->ShowCreatedWidget(route_id, initial_pos); } void BrowserPluginGuest::OnTakeFocus(bool reverse) { @@ -1478,8 +1502,7 @@ void BrowserPluginGuest::OnUpdateRect( // The scaling change can happen due to asynchronous updates of the DPI on a // resolution change. if (((auto_size_enabled_ && InAutoSizeBounds(params.view_size)) || - (params.view_size.width() == damage_view_size().width() && - params.view_size.height() == damage_view_size().height())) && + (params.view_size == damage_view_size())) && params.scale_factor == damage_buffer_scale_factor()) { TransportDIB* dib = GetWebContents()->GetRenderProcessHost()-> GetTransportDIB(params.bitmap); diff --git a/content/browser/browser_plugin/browser_plugin_guest.h b/content/browser/browser_plugin/browser_plugin_guest.h index 155d9f3bb6..a298922506 100644 --- a/content/browser/browser_plugin/browser_plugin_guest.h +++ b/content/browser/browser_plugin/browser_plugin_guest.h @@ -254,6 +254,7 @@ class CONTENT_EXPORT BrowserPluginGuest // Returns whether BrowserPluginGuest is interested in receiving the given // |message|. static bool ShouldForwardToBrowserPluginGuest(const IPC::Message& message); + gfx::Rect ToGuestRect(const gfx::Rect& rect); void DragSourceEndedAt(int client_x, int client_y, int screen_x, int screen_y, WebKit::WebDragOperation operation); @@ -391,6 +392,7 @@ class CONTENT_EXPORT BrowserPluginGuest void OnTerminateGuest(int instance_id); void OnUnlockMouse(); void OnUnlockMouseAck(int instance_id); + void OnUpdateGeometry(int instance_id, const gfx::Rect& view_rect); void OnUpdateRectACK( int instance_id, const BrowserPluginHostMsg_AutoSize_Params& auto_size_params, diff --git a/content/browser/browser_plugin/browser_plugin_guest_manager.cc b/content/browser/browser_plugin/browser_plugin_guest_manager.cc index 081f33246a..1a33e9ab12 100644 --- a/content/browser/browser_plugin/browser_plugin_guest_manager.cc +++ b/content/browser/browser_plugin/browser_plugin_guest_manager.cc @@ -230,4 +230,19 @@ void BrowserPluginGuestManager::OnUnhandledSwapBuffersACK( sync_point); } +void BrowserPluginGuestManager::DidSendScreenRects( + WebContents* embedder_web_contents, RenderWidgetHostImpl* rwh) { + // TODO(lazyboy): Generalize iterating over guest instances and performing + // actions on the guests. + for (GuestInstanceMap::iterator it = + guest_web_contents_by_instance_id_.begin(); + it != guest_web_contents_by_instance_id_.end(); ++it) { + BrowserPluginGuest* guest = it->second->GetBrowserPluginGuest(); + if (embedder_web_contents == guest->embedder_web_contents()) { + static_cast<RenderViewHostImpl*>( + guest->GetWebContents()->GetRenderViewHost())->SendScreenRects(); + } + } +} + } // namespace content diff --git a/content/browser/browser_plugin/browser_plugin_guest_manager.h b/content/browser/browser_plugin/browser_plugin_guest_manager.h index 4e1ba287b4..f915362dbe 100644 --- a/content/browser/browser_plugin/browser_plugin_guest_manager.h +++ b/content/browser/browser_plugin/browser_plugin_guest_manager.h @@ -31,6 +31,7 @@ namespace content { class BrowserPluginGuest; class BrowserPluginHostFactory; class RenderProcessHostImpl; +class RenderWidgetHostImpl; class SiteInstance; class WebContents; class WebContentsImpl; @@ -79,6 +80,9 @@ class CONTENT_EXPORT BrowserPluginGuestManager : bool CanEmbedderAccessInstanceIDMaybeKill(int embedder_render_process_id, int instance_id) const; + void DidSendScreenRects(WebContents* embedder_web_contents, + RenderWidgetHostImpl* rwh); + void OnMessageReceived(const IPC::Message& message, int render_process_id); private: diff --git a/content/browser/browser_plugin/browser_plugin_host_browsertest.cc b/content/browser/browser_plugin/browser_plugin_host_browsertest.cc index 818aa2756c..c67be30f31 100644 --- a/content/browser/browser_plugin/browser_plugin_host_browsertest.cc +++ b/content/browser/browser_plugin/browser_plugin_host_browsertest.cc @@ -29,6 +29,9 @@ #include "content/test/content_browser_test.h" #include "content/test/content_browser_test_utils.h" #include "net/base/net_util.h" +#include "net/test/embedded_test_server/embedded_test_server.h" +#include "net/test/embedded_test_server/http_response.h" +#include "net/test/embedded_test_server/http_request.h" #include "net/test/spawned_test_server/spawned_test_server.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" #include "webkit/glue/webdropdata.h" @@ -309,8 +312,8 @@ class BrowserPluginHostTest : public ContentBrowserTest { const std::string& guest_url, bool is_guest_data_url, const std::string& embedder_code) { - ASSERT_TRUE(test_server()->Start()); - GURL test_url(test_server()->GetURL(embedder_url)); + ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); + GURL test_url(embedded_test_server()->GetURL(embedder_url)); NavigateToURL(shell(), test_url); WebContentsImpl* embedder_web_contents = static_cast<WebContentsImpl*>( @@ -326,7 +329,7 @@ class BrowserPluginHostTest : public ContentBrowserTest { ExecuteSyncJSFunction(rvh, embedder_code); if (!is_guest_data_url) { - test_url = test_server()->GetURL(guest_url); + test_url = embedded_test_server()->GetURL(guest_url); ExecuteSyncJSFunction( rvh, base::StringPrintf("SetSrc('%s');", test_url.spec().c_str())); } else { @@ -388,7 +391,7 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, content::BrowserPluginGuest::set_factory_for_testing( TestShortHangTimeoutGuestFactory::GetInstance()); const char kEmbedderURL[] = - "files/browser_plugin_embedder_guest_unresponsive.html"; + "/browser_plugin_embedder_guest_unresponsive.html"; StartBrowserPluginTest( kEmbedderURL, kHTMLForGuestBusyLoop, true, std::string()); // Wait until the busy loop starts. @@ -444,7 +447,7 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, NavigateAfterResize) { const gfx::Size nxt_size = gfx::Size(100, 200); const std::string embedder_code = base::StringPrintf( "SetSize(%d, %d);", nxt_size.width(), nxt_size.height()); - const char kEmbedderURL[] = "files/browser_plugin_embedder.html"; + const char kEmbedderURL[] = "/browser_plugin_embedder.html"; StartBrowserPluginTest(kEmbedderURL, kHTMLForGuest, true, embedder_code); // Wait for the guest to receive a damage buffer of size 100x200. @@ -453,8 +456,8 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, NavigateAfterResize) { } IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, AdvanceFocus) { - const char kEmbedderURL[] = "files/browser_plugin_focus.html"; - const char* kGuestURL = "files/browser_plugin_focus_child.html"; + const char kEmbedderURL[] = "/browser_plugin_focus.html"; + const char* kGuestURL = "/browser_plugin_focus_child.html"; StartBrowserPluginTest(kEmbedderURL, kGuestURL, false, std::string()); SimulateMouseClick(test_embedder()->web_contents(), 0, @@ -485,7 +488,7 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, EmbedderChangedAfterSwap) { ASSERT_TRUE(https_server.Start()); // 1. Load an embedder page with one guest in it. - const char kEmbedderURL[] = "files/browser_plugin_embedder.html"; + const char kEmbedderURL[] = "/browser_plugin_embedder.html"; StartBrowserPluginTest(kEmbedderURL, kHTMLForGuest, true, std::string()); // 2. Navigate to a URL in https, so we trigger a RenderViewHost swap. @@ -511,14 +514,14 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, EmbedderChangedAfterSwap) { // therefore the embedder created on first page navigation stays the same in // web_contents. IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, EmbedderSameAfterNav) { - const char kEmbedderURL[] = "files/browser_plugin_embedder.html"; + const char kEmbedderURL[] = "/browser_plugin_embedder.html"; StartBrowserPluginTest(kEmbedderURL, kHTMLForGuest, true, std::string()); WebContentsImpl* embedder_web_contents = test_embedder()->web_contents(); // Navigate to another page in same host and port, so RenderViewHost swap // does not happen and existing embedder doesn't change in web_contents. - GURL test_url_new(test_server()->GetURL( - "files/browser_plugin_title_change.html")); + GURL test_url_new(embedded_test_server()->GetURL( + "/browser_plugin_title_change.html")); const string16 expected_title = ASCIIToUTF16("done"); content::TitleWatcher title_watcher(shell()->web_contents(), expected_title); NavigateToURL(shell(), test_url_new); @@ -536,7 +539,7 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, EmbedderSameAfterNav) { // This test verifies that hiding the embedder also hides the guest. IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, BrowserPluginVisibilityChanged) { - const char kEmbedderURL[] = "files/browser_plugin_embedder.html"; + const char kEmbedderURL[] = "/browser_plugin_embedder.html"; StartBrowserPluginTest(kEmbedderURL, kHTMLForGuest, true, std::string()); // Hide the Browser Plugin. @@ -550,7 +553,7 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, BrowserPluginVisibilityChanged) { } IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, EmbedderVisibilityChanged) { - const char kEmbedderURL[] = "files/browser_plugin_embedder.html"; + const char kEmbedderURL[] = "/browser_plugin_embedder.html"; StartBrowserPluginTest(kEmbedderURL, kHTMLForGuest, true, std::string()); // Hide the embedder. @@ -562,7 +565,7 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, EmbedderVisibilityChanged) { // This test verifies that calling the reload method reloads the guest. IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, ReloadGuest) { - const char kEmbedderURL[] = "files/browser_plugin_embedder.html"; + const char kEmbedderURL[] = "/browser_plugin_embedder.html"; StartBrowserPluginTest(kEmbedderURL, kHTMLForGuest, true, std::string()); test_guest()->ResetUpdateRectCount(); @@ -576,7 +579,7 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, ReloadGuest) { // This test verifies that calling the stop method forwards the stop request // to the guest's WebContents. IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, StopGuest) { - const char kEmbedderURL[] = "files/browser_plugin_embedder.html"; + const char kEmbedderURL[] = "/browser_plugin_embedder.html"; StartBrowserPluginTest(kEmbedderURL, kHTMLForGuest, true, std::string()); RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>( @@ -588,7 +591,7 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, StopGuest) { // Verifies that installing/uninstalling touch-event handlers in the guest // plugin correctly updates the touch-event handling state in the embedder. IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, AcceptTouchEvents) { - const char kEmbedderURL[] = "files/browser_plugin_embedder.html"; + const char kEmbedderURL[] = "/browser_plugin_embedder.html"; StartBrowserPluginTest( kEmbedderURL, kHTMLForGuestTouchHandler, true, std::string()); @@ -616,7 +619,7 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, AcceptTouchEvents) { } IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, Renavigate) { - const char kEmbedderURL[] = "files/browser_plugin_embedder.html"; + const char kEmbedderURL[] = "/browser_plugin_embedder.html"; StartBrowserPluginTest( kEmbedderURL, GetHTMLForGuestWithTitle("P1"), true, std::string()); RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>( @@ -712,7 +715,7 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, Renavigate) { // This tests verifies that reloading the embedder does not crash the browser // and that the guest is reset. IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, ReloadEmbedder) { - const char kEmbedderURL[] = "files/browser_plugin_embedder.html"; + const char kEmbedderURL[] = "/browser_plugin_embedder.html"; StartBrowserPluginTest(kEmbedderURL, kHTMLForGuest, true, std::string()); RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>( test_embedder()->web_contents()->GetRenderViewHost()); @@ -763,7 +766,7 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, ReloadEmbedder) { } IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, TerminateGuest) { - const char kEmbedderURL[] = "files/browser_plugin_embedder.html"; + const char kEmbedderURL[] = "/browser_plugin_embedder.html"; StartBrowserPluginTest(kEmbedderURL, kHTMLForGuest, true, std::string()); RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>( @@ -777,7 +780,7 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, TerminateGuest) { // This test verifies that the guest is responsive after crashing and going back // to a previous navigation entry. IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, BackAfterTerminateGuest) { - const char* kEmbedderURL = "files/browser_plugin_embedder.html"; + const char* kEmbedderURL = "/browser_plugin_embedder.html"; StartBrowserPluginTest( kEmbedderURL, GetHTMLForGuestWithTitle("P1"), true, std::string()); RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>( @@ -820,7 +823,7 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, BackAfterTerminateGuest) { } IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, LoadStart) { - const char kEmbedderURL[] = "files/browser_plugin_embedder.html"; + const char kEmbedderURL[] = "/browser_plugin_embedder.html"; StartBrowserPluginTest(kEmbedderURL, "about:blank", true, std::string()); const string16 expected_title = ASCIIToUTF16(kHTMLForGuest); @@ -836,18 +839,59 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, LoadStart) { EXPECT_EQ(expected_title, actual_title); } +namespace { + +class EmptyHttpResponse : public net::test_server::HttpResponse { + public: + virtual std::string ToResponseString() const OVERRIDE { + return std::string(); + } +}; + +// Handles |request| by serving an empty response. +scoped_ptr<net::test_server::HttpResponse> EmptyResponseHandler( + const std::string& path, + const net::test_server::HttpRequest& request) { + if (StartsWithASCII(path, request.relative_url, true)) { + return scoped_ptr<net::test_server::HttpResponse>( + new EmptyHttpResponse); + } + + return scoped_ptr<net::test_server::HttpResponse>(NULL); +} + +// Handles |request| by serving a redirect response. +scoped_ptr<net::test_server::HttpResponse> RedirectResponseHandler( + const std::string& path, + const GURL& redirect_target, + const net::test_server::HttpRequest& request) { + if (!StartsWithASCII(path, request.relative_url, true)) + return scoped_ptr<net::test_server::HttpResponse>(NULL); + + scoped_ptr<net::test_server::BasicHttpResponse> http_response( + new net::test_server::BasicHttpResponse); + http_response->set_code(net::test_server::MOVED); + http_response->AddCustomHeader("Location", redirect_target.spec()); + return http_response.PassAs<net::test_server::HttpResponse>(); +} + +} // namespace + IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, LoadAbort) { - const char kEmbedderURL[] = "files/browser_plugin_embedder.html"; + const char kEmbedderURL[] = "/browser_plugin_embedder.html"; StartBrowserPluginTest(kEmbedderURL, "about:blank", true, std::string()); { // Navigate the guest to "close-socket". + const char kEmptyResponsePath[] = "/close-socket"; + embedded_test_server()->RegisterRequestHandler( + base::Bind(&EmptyResponseHandler, kEmptyResponsePath)); const string16 expected_title = ASCIIToUTF16("ERR_EMPTY_RESPONSE"); content::TitleWatcher title_watcher(test_embedder()->web_contents(), expected_title); RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>( test_embedder()->web_contents()->GetRenderViewHost()); - GURL test_url = test_server()->GetURL("close-socket"); + GURL test_url = embedded_test_server()->GetURL(kEmptyResponsePath); ExecuteSyncJSFunction( rvh, base::StringPrintf("SetSrc('%s');", test_url.spec().c_str())); string16 actual_title = title_watcher.WaitAndGetTitle(); @@ -890,7 +934,7 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, LoadAbort) { } IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, LoadRedirect) { - const char kEmbedderURL[] = "files/browser_plugin_embedder.html"; + const char kEmbedderURL[] = "/browser_plugin_embedder.html"; StartBrowserPluginTest(kEmbedderURL, "about:blank", true, std::string()); const string16 expected_title = ASCIIToUTF16("redirected"); @@ -898,8 +942,12 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, LoadRedirect) { expected_title); // Navigate with a redirect and wait until the title changes. - GURL redirect_url(test_server()->GetURL( - "server-redirect?files/title1.html")); + const char kRedirectResponsePath[] = "/server-redirect"; + embedded_test_server()->RegisterRequestHandler( + base::Bind(&RedirectResponseHandler, + kRedirectResponsePath, + embedded_test_server()->GetURL("/title1.html"))); + GURL redirect_url(embedded_test_server()->GetURL(kRedirectResponsePath)); RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>( test_embedder()->web_contents()->GetRenderViewHost()); ExecuteSyncJSFunction( @@ -917,7 +965,8 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, LoadRedirect) { value = content::ExecuteScriptAndGetValue(rvh, "redirectNewUrl"); EXPECT_TRUE(value->GetAsString(&result)); - EXPECT_EQ(test_server()->GetURL("files/title1.html").spec().c_str(), result); + EXPECT_EQ(embedded_test_server()->GetURL("/title1.html").spec().c_str(), + result); } // Always failing in the win7_aura try bot. See http://crbug.com/181107. @@ -930,7 +979,7 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, LoadRedirect) { // Tests that a drag-n-drop over the browser plugin in the embedder happens // correctly. IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, MAYBE_AcceptDragEvents) { - const char kEmbedderURL[] = "files/browser_plugin_dragging.html"; + const char kEmbedderURL[] = "/browser_plugin_dragging.html"; StartBrowserPluginTest( kEmbedderURL, kHTMLForGuestAcceptDrag, true, std::string()); @@ -986,8 +1035,8 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, MAYBE_AcceptDragEvents) { // message. IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, PostMessage) { const char* kTesting = "testing123"; - const char* kEmbedderURL = "files/browser_plugin_embedder.html"; - const char* kGuestURL = "files/browser_plugin_post_message_guest.html"; + const char* kEmbedderURL = "/browser_plugin_embedder.html"; + const char* kGuestURL = "/browser_plugin_post_message_guest.html"; StartBrowserPluginTest(kEmbedderURL, kGuestURL, false, std::string()); RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>( test_embedder()->web_contents()->GetRenderViewHost()); @@ -1014,8 +1063,8 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, PostMessage) { // iframe targeting is fixed (see http://crbug.com/153701). IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, DISABLED_PostMessageToIFrame) { const char* kTesting = "testing123"; - const char* kEmbedderURL = "files/browser_plugin_embedder.html"; - const char* kGuestURL = "files/browser_plugin_post_message_guest.html"; + const char* kEmbedderURL = "/browser_plugin_embedder.html"; + const char* kGuestURL = "/browser_plugin_post_message_guest.html"; StartBrowserPluginTest(kEmbedderURL, kGuestURL, false, std::string()); RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>( test_embedder()->web_contents()->GetRenderViewHost()); @@ -1038,8 +1087,8 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, DISABLED_PostMessageToIFrame) { RenderViewHostImpl* guest_rvh = static_cast<RenderViewHostImpl*>( test_guest()->web_contents()->GetRenderViewHost()); - GURL test_url = test_server()->GetURL( - "files/browser_plugin_post_message_guest.html"); + GURL test_url = embedded_test_server()->GetURL( + "/browser_plugin_post_message_guest.html"); ExecuteSyncJSFunction( guest_rvh, base::StringPrintf( @@ -1061,7 +1110,7 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, DISABLED_PostMessageToIFrame) { } IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, LoadStop) { - const char* kEmbedderURL = "files/browser_plugin_embedder.html"; + const char* kEmbedderURL = "/browser_plugin_embedder.html"; StartBrowserPluginTest(kEmbedderURL, "about:blank", true, std::string()); const string16 expected_title = ASCIIToUTF16("loadStop"); @@ -1078,7 +1127,7 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, LoadStop) { } IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, LoadCommit) { - const char* kEmbedderURL = "files/browser_plugin_embedder.html"; + const char* kEmbedderURL = "/browser_plugin_embedder.html"; StartBrowserPluginTest(kEmbedderURL, "about:blank", true, std::string()); const string16 expected_title = ASCIIToUTF16( @@ -1103,7 +1152,7 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, LoadCommit) { // This test verifies that if a browser plugin is hidden before navigation, // the guest starts off hidden. IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, HiddenBeforeNavigation) { - const char* kEmbedderURL = "files/browser_plugin_embedder.html"; + const char* kEmbedderURL = "/browser_plugin_embedder.html"; const std::string embedder_code = "document.getElementById('plugin').style.visibility = 'hidden'"; StartBrowserPluginTest( @@ -1114,7 +1163,7 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, HiddenBeforeNavigation) { // This test verifies that if we lose the guest, and get a new one, // the new guest will inherit the visibility state of the old guest. IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, VisibilityPreservation) { - const char* kEmbedderURL = "files/browser_plugin_embedder.html"; + const char* kEmbedderURL = "/browser_plugin_embedder.html"; StartBrowserPluginTest(kEmbedderURL, kHTMLForGuest, true, std::string()); RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>( test_embedder()->web_contents()->GetRenderViewHost()); @@ -1135,7 +1184,7 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, VisibilityPreservation) { // This test verifies that if a browser plugin is focused before navigation then // the guest starts off focused. IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, FocusBeforeNavigation) { - const char* kEmbedderURL = "files/browser_plugin_embedder.html"; + const char* kEmbedderURL = "/browser_plugin_embedder.html"; const std::string embedder_code = "document.getElementById('plugin').focus();"; StartBrowserPluginTest( @@ -1154,7 +1203,7 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, FocusBeforeNavigation) { // the new guest will inherit the focus state of the old guest. // crbug.com/170249 IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, DISABLED_FocusPreservation) { - const char* kEmbedderURL = "files/browser_plugin_embedder.html"; + const char* kEmbedderURL = "/browser_plugin_embedder.html"; StartBrowserPluginTest(kEmbedderURL, kHTMLForGuest, true, std::string()); RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>( test_embedder()->web_contents()->GetRenderViewHost()); @@ -1193,7 +1242,7 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, DISABLED_FocusPreservation) { } IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, FocusTracksEmbedder) { - const char* kEmbedderURL = "files/browser_plugin_embedder.html"; + const char* kEmbedderURL = "/browser_plugin_embedder.html"; StartBrowserPluginTest(kEmbedderURL, kHTMLForGuest, true, std::string()); RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>( test_embedder()->web_contents()->GetRenderViewHost()); @@ -1221,7 +1270,7 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, FocusTracksEmbedder) { // This test verifies that if a browser plugin is in autosize mode before // navigation then the guest starts auto-sized. IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, AutoSizeBeforeNavigation) { - const char* kEmbedderURL = "files/browser_plugin_embedder.html"; + const char* kEmbedderURL = "/browser_plugin_embedder.html"; const std::string embedder_code = "document.getElementById('plugin').minwidth = 300;" "document.getElementById('plugin').minheight = 200;" @@ -1237,7 +1286,7 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, AutoSizeBeforeNavigation) { // This test verifies that enabling autosize resizes the guest and triggers // a 'sizechanged' event. IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, AutoSizeAfterNavigation) { - const char* kEmbedderURL = "files/browser_plugin_embedder.html"; + const char* kEmbedderURL = "/browser_plugin_embedder.html"; StartBrowserPluginTest( kEmbedderURL, kHTMLForGuestWithSize, true, std::string()); RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>( @@ -1277,7 +1326,7 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, AutoSizeAfterNavigation) { // Test for regression http://crbug.com/162961. IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, GetRenderViewHostAtPositionTest) { - const char kEmbedderURL[] = "files/browser_plugin_embedder.html"; + const char kEmbedderURL[] = "/browser_plugin_embedder.html"; const std::string embedder_code = base::StringPrintf("SetSize(%d, %d);", 100, 100); StartBrowserPluginTest(kEmbedderURL, kHTMLForGuestWithSize, true, @@ -1298,8 +1347,8 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, GetRenderViewHostAtPositionTest) { #endif IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, MAYBE_ChangeWindowName) { - const char kEmbedderURL[] = "files/browser_plugin_naming_embedder.html"; - const char* kGuestURL = "files/browser_plugin_naming_guest.html"; + const char kEmbedderURL[] = "/browser_plugin_naming_embedder.html"; + const char* kGuestURL = "/browser_plugin_naming_guest.html"; StartBrowserPluginTest(kEmbedderURL, kGuestURL, false, std::string()); RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>( @@ -1345,7 +1394,7 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, MAYBE_ChangeWindowName) { // This test verifies that all autosize attributes can be removed // without crashing the plugin, or throwing errors. IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, RemoveAutosizeAttributes) { - const char* kEmbedderURL = "files/browser_plugin_embedder.html"; + const char* kEmbedderURL = "/browser_plugin_embedder.html"; const std::string embedder_code = "document.getElementById('plugin').minwidth = 300;" "document.getElementById('plugin').minheight = 200;" @@ -1371,7 +1420,7 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, RemoveAutosizeAttributes) { // This test verifies that autosize works when some of the parameters are unset. IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, PartialAutosizeAttributes) { - const char* kEmbedderURL = "files/browser_plugin_embedder.html"; + const char* kEmbedderURL = "/browser_plugin_embedder.html"; const std::string embedder_code = "document.getElementById('plugin').minwidth = 300;" "document.getElementById('plugin').minheight = 200;" diff --git a/content/browser/browser_plugin/test_browser_plugin_guest.cc b/content/browser/browser_plugin/test_browser_plugin_guest.cc index 083ea5a19f..5205752de1 100644 --- a/content/browser/browser_plugin/test_browser_plugin_guest.cc +++ b/content/browser/browser_plugin/test_browser_plugin_guest.cc @@ -265,10 +265,10 @@ void TestBrowserPluginGuest::OnStop(int instance_id) { void TestBrowserPluginGuest::SetDamageBuffer( const BrowserPluginHostMsg_ResizeGuest_Params& params) { ++damage_buffer_call_count_; - last_damage_buffer_size_ = params.view_size; + last_damage_buffer_size_ = params.view_rect.size(); if (waiting_for_damage_buffer_with_size_ && - expected_damage_buffer_size_ == params.view_size && + expected_damage_buffer_size_ == params.view_rect.size() && damage_buffer_message_loop_runner_) { damage_buffer_message_loop_runner_->Quit(); waiting_for_damage_buffer_with_size_ = false; diff --git a/content/browser/browser_url_handler_impl.cc b/content/browser/browser_url_handler_impl.cc index e10e997132..126e48554f 100644 --- a/content/browser/browser_url_handler_impl.cc +++ b/content/browser/browser_url_handler_impl.cc @@ -36,7 +36,7 @@ static bool HandleViewSource(GURL* url, } if (!is_sub_scheme_allowed) { - *url = GURL(chrome::kAboutBlankURL); + *url = GURL(kAboutBlankURL); return false; } diff --git a/content/browser/child_process_security_policy_impl.cc b/content/browser/child_process_security_policy_impl.cc index 45694faf1d..89c8efe72d 100644 --- a/content/browser/child_process_security_policy_impl.cc +++ b/content/browser/child_process_security_policy_impl.cc @@ -20,7 +20,7 @@ #include "googleurl/src/gurl.h" #include "net/base/net_util.h" #include "net/url_request/url_request.h" -#include "webkit/fileapi/isolated_context.h" +#include "webkit/browser/fileapi/isolated_context.h" namespace content { @@ -547,7 +547,7 @@ bool ChildProcessSecurityPolicyImpl::CanRequestURL( return CanRequestURL(child_id, child_url); } - if (LowerCaseEqualsASCII(url.spec(), chrome::kAboutBlankURL)) + if (LowerCaseEqualsASCII(url.spec(), kAboutBlankURL)) return true; // Every child process can request <about:blank>. // URLs like <about:memory> and <about:crash> shouldn't be requestable by diff --git a/content/browser/devtools/devtools_http_handler_impl.cc b/content/browser/devtools/devtools_http_handler_impl.cc index cea21562de..bcbfce0017 100644 --- a/content/browser/devtools/devtools_http_handler_impl.cc +++ b/content/browser/devtools/devtools_http_handler_impl.cc @@ -47,8 +47,8 @@ #include "third_party/WebKit/Source/Platform/chromium/public/WebString.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebDevToolsAgent.h" #include "ui/base/layout.h" -#include "webkit/user_agent/user_agent.h" -#include "webkit/user_agent/user_agent_util.h" +#include "webkit/common/user_agent/user_agent.h" +#include "webkit/common/user_agent/user_agent_util.h" namespace content { @@ -489,7 +489,7 @@ void DevToolsHttpHandlerImpl::OnJsonRequestUI( version.SetString("Browser", content::GetContentClient()->GetProduct()); version.SetString("User-Agent", - webkit_glue::GetUserAgent(GURL(chrome::kAboutBlankURL))); + webkit_glue::GetUserAgent(GURL(kAboutBlankURL))); SendJson(connection_id, net::HTTP_OK, &version, std::string()); return; } diff --git a/content/browser/devtools/devtools_resources.target.darwin-arm.mk b/content/browser/devtools/devtools_resources.target.darwin-arm.mk index 1d4262f0a4..a0fc8f39ed 100644 --- a/content/browser/devtools/devtools_resources.target.darwin-arm.mk +++ b/content/browser/devtools/devtools_resources.target.darwin-arm.mk @@ -16,12 +16,12 @@ GYP_TARGET_DEPENDENCIES := \ ### Rules for action "devtools_resources": $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_local_path := $(LOCAL_PATH) -$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir) -$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir) +$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir)) +$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir)) $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH)) $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: $(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/clique_unittest.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/c_format_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_writer_base_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/rc_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/rc_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/gather/txt_unittest.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grd_reader_unittest.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/grit_runner_unittest.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/lazy_re_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/base_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/include_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/io_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/message_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/misc_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/structure_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/pseudo_unittest.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/tclib_unittest.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/build_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb_unittest.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/util_unittest.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader_unittest.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES) @echo "Gyp action: Generating resources from $(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd ($@)" - $(hide)cd $(gyp_local_path)/content/browser/devtools; mkdir -p $(gyp_shared_intermediate_dir)/webkit/grit $(gyp_shared_intermediate_dir)/webkit; python ../../../tools/grit/grit.py -i "$(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd" build -f GRIT_DIR/../gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/webkit" -D "SHARED_INTERMEDIATE_DIR=$(gyp_shared_intermediate_dir)" -D _chromium -E "CHROMIUM_BUILD=chromium" -D android -E "ANDROID_JAVA_TAGGED_ONLY=true" -D use_concatenated_impulse_responses + $(hide)cd $(gyp_local_path)/content/browser/devtools; mkdir -p $(gyp_shared_intermediate_dir)/webkit/grit $(gyp_shared_intermediate_dir)/webkit; python ../../../tools/grit/grit.py -i "$(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd" build -f GRIT_DIR/../gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/webkit" -D "SHARED_INTERMEDIATE_DIR=$(gyp_shared_intermediate_dir)" -D _chromium -E "CHROMIUM_BUILD=chromium" -t android -E "ANDROID_JAVA_TAGGED_ONLY=true" -D use_concatenated_impulse_responses $(gyp_shared_intermediate_dir)/webkit/devtools_resources.pak: $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h ; $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources_map.cc: $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h ; diff --git a/content/browser/devtools/devtools_resources.target.darwin-x86.mk b/content/browser/devtools/devtools_resources.target.darwin-x86.mk index 1d4262f0a4..a0fc8f39ed 100644 --- a/content/browser/devtools/devtools_resources.target.darwin-x86.mk +++ b/content/browser/devtools/devtools_resources.target.darwin-x86.mk @@ -16,12 +16,12 @@ GYP_TARGET_DEPENDENCIES := \ ### Rules for action "devtools_resources": $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_local_path := $(LOCAL_PATH) -$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir) -$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir) +$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir)) +$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir)) $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH)) $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: $(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/clique_unittest.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/c_format_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_writer_base_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/rc_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/rc_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/gather/txt_unittest.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grd_reader_unittest.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/grit_runner_unittest.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/lazy_re_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/base_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/include_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/io_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/message_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/misc_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/structure_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/pseudo_unittest.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/tclib_unittest.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/build_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb_unittest.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/util_unittest.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader_unittest.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES) @echo "Gyp action: Generating resources from $(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd ($@)" - $(hide)cd $(gyp_local_path)/content/browser/devtools; mkdir -p $(gyp_shared_intermediate_dir)/webkit/grit $(gyp_shared_intermediate_dir)/webkit; python ../../../tools/grit/grit.py -i "$(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd" build -f GRIT_DIR/../gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/webkit" -D "SHARED_INTERMEDIATE_DIR=$(gyp_shared_intermediate_dir)" -D _chromium -E "CHROMIUM_BUILD=chromium" -D android -E "ANDROID_JAVA_TAGGED_ONLY=true" -D use_concatenated_impulse_responses + $(hide)cd $(gyp_local_path)/content/browser/devtools; mkdir -p $(gyp_shared_intermediate_dir)/webkit/grit $(gyp_shared_intermediate_dir)/webkit; python ../../../tools/grit/grit.py -i "$(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd" build -f GRIT_DIR/../gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/webkit" -D "SHARED_INTERMEDIATE_DIR=$(gyp_shared_intermediate_dir)" -D _chromium -E "CHROMIUM_BUILD=chromium" -t android -E "ANDROID_JAVA_TAGGED_ONLY=true" -D use_concatenated_impulse_responses $(gyp_shared_intermediate_dir)/webkit/devtools_resources.pak: $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h ; $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources_map.cc: $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h ; diff --git a/content/browser/devtools/devtools_resources.target.linux-arm.mk b/content/browser/devtools/devtools_resources.target.linux-arm.mk index 1d4262f0a4..a0fc8f39ed 100644 --- a/content/browser/devtools/devtools_resources.target.linux-arm.mk +++ b/content/browser/devtools/devtools_resources.target.linux-arm.mk @@ -16,12 +16,12 @@ GYP_TARGET_DEPENDENCIES := \ ### Rules for action "devtools_resources": $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_local_path := $(LOCAL_PATH) -$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir) -$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir) +$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir)) +$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir)) $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH)) $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: $(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/clique_unittest.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/c_format_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_writer_base_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/rc_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/rc_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/gather/txt_unittest.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grd_reader_unittest.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/grit_runner_unittest.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/lazy_re_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/base_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/include_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/io_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/message_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/misc_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/structure_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/pseudo_unittest.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/tclib_unittest.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/build_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb_unittest.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/util_unittest.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader_unittest.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES) @echo "Gyp action: Generating resources from $(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd ($@)" - $(hide)cd $(gyp_local_path)/content/browser/devtools; mkdir -p $(gyp_shared_intermediate_dir)/webkit/grit $(gyp_shared_intermediate_dir)/webkit; python ../../../tools/grit/grit.py -i "$(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd" build -f GRIT_DIR/../gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/webkit" -D "SHARED_INTERMEDIATE_DIR=$(gyp_shared_intermediate_dir)" -D _chromium -E "CHROMIUM_BUILD=chromium" -D android -E "ANDROID_JAVA_TAGGED_ONLY=true" -D use_concatenated_impulse_responses + $(hide)cd $(gyp_local_path)/content/browser/devtools; mkdir -p $(gyp_shared_intermediate_dir)/webkit/grit $(gyp_shared_intermediate_dir)/webkit; python ../../../tools/grit/grit.py -i "$(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd" build -f GRIT_DIR/../gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/webkit" -D "SHARED_INTERMEDIATE_DIR=$(gyp_shared_intermediate_dir)" -D _chromium -E "CHROMIUM_BUILD=chromium" -t android -E "ANDROID_JAVA_TAGGED_ONLY=true" -D use_concatenated_impulse_responses $(gyp_shared_intermediate_dir)/webkit/devtools_resources.pak: $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h ; $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources_map.cc: $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h ; diff --git a/content/browser/devtools/devtools_resources.target.linux-x86.mk b/content/browser/devtools/devtools_resources.target.linux-x86.mk index 1d4262f0a4..a0fc8f39ed 100644 --- a/content/browser/devtools/devtools_resources.target.linux-x86.mk +++ b/content/browser/devtools/devtools_resources.target.linux-x86.mk @@ -16,12 +16,12 @@ GYP_TARGET_DEPENDENCIES := \ ### Rules for action "devtools_resources": $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_local_path := $(LOCAL_PATH) -$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir) -$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir) +$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir)) +$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir)) $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH)) $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: $(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/clique_unittest.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/c_format_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_writer_base_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/rc_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/rc_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/gather/txt_unittest.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grd_reader_unittest.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/grit_runner_unittest.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/lazy_re_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/base_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/include_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/io_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/message_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/misc_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/structure_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/pseudo_unittest.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/tclib_unittest.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/build_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb_unittest.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/util_unittest.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader_unittest.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES) @echo "Gyp action: Generating resources from $(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd ($@)" - $(hide)cd $(gyp_local_path)/content/browser/devtools; mkdir -p $(gyp_shared_intermediate_dir)/webkit/grit $(gyp_shared_intermediate_dir)/webkit; python ../../../tools/grit/grit.py -i "$(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd" build -f GRIT_DIR/../gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/webkit" -D "SHARED_INTERMEDIATE_DIR=$(gyp_shared_intermediate_dir)" -D _chromium -E "CHROMIUM_BUILD=chromium" -D android -E "ANDROID_JAVA_TAGGED_ONLY=true" -D use_concatenated_impulse_responses + $(hide)cd $(gyp_local_path)/content/browser/devtools; mkdir -p $(gyp_shared_intermediate_dir)/webkit/grit $(gyp_shared_intermediate_dir)/webkit; python ../../../tools/grit/grit.py -i "$(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd" build -f GRIT_DIR/../gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/webkit" -D "SHARED_INTERMEDIATE_DIR=$(gyp_shared_intermediate_dir)" -D _chromium -E "CHROMIUM_BUILD=chromium" -t android -E "ANDROID_JAVA_TAGGED_ONLY=true" -D use_concatenated_impulse_responses $(gyp_shared_intermediate_dir)/webkit/devtools_resources.pak: $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h ; $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources_map.cc: $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h ; diff --git a/content/browser/download/download_browsertest.cc b/content/browser/download/download_browsertest.cc index 9d1a3c6024..8f1e542731 100644 --- a/content/browser/download/download_browsertest.cc +++ b/content/browser/download/download_browsertest.cc @@ -1378,4 +1378,185 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeWithFileFinalRenameError) { EXPECT_EQ(download->GetState(), DownloadItem::COMPLETE); } +// An interrupted download should remove the intermediate file when it is +// cancelled. +IN_PROC_BROWSER_TEST_F(DownloadContentTest, CancelInterruptedDownload) { + CommandLine::ForCurrentProcess()->AppendSwitch( + switches::kEnableDownloadResumption); + ASSERT_TRUE(test_server()->Start()); + + GURL url1 = test_server()->GetURL( + base::StringPrintf("rangereset?size=%d&rst_boundary=%d", + GetSafeBufferChunk() * 3, GetSafeBufferChunk())); + + DownloadItem* download(StartDownloadAndReturnItem(url1)); + WaitForData(download, GetSafeBufferChunk()); + + ReleaseRSTAndConfirmInterruptForResume(download); + ConfirmFileStatusForResume( + download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3, + base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload"))); + + base::FilePath intermediate_path(download->GetFullPath()); + ASSERT_FALSE(intermediate_path.empty()); + EXPECT_TRUE(file_util::PathExists(intermediate_path)); + + download->Cancel(true /* user_cancel */); + RunAllPendingInMessageLoop(BrowserThread::FILE); + RunAllPendingInMessageLoop(); + + // The intermediate file should now be gone. + EXPECT_FALSE(file_util::PathExists(intermediate_path)); + EXPECT_TRUE(download->GetFullPath().empty()); +} + +IN_PROC_BROWSER_TEST_F(DownloadContentTest, RemoveDownload) { + CommandLine::ForCurrentProcess()->AppendSwitch( + switches::kEnableDownloadResumption); + ASSERT_TRUE(test_server()->Start()); + + // An interrupted download should remove the intermediate file when it is + // removed. + { + GURL url1 = test_server()->GetURL( + base::StringPrintf("rangereset?size=%d&rst_boundary=%d", + GetSafeBufferChunk() * 3, GetSafeBufferChunk())); + + DownloadItem* download(StartDownloadAndReturnItem(url1)); + WaitForData(download, GetSafeBufferChunk()); + ReleaseRSTAndConfirmInterruptForResume(download); + ConfirmFileStatusForResume( + download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3, + base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload"))); + + base::FilePath intermediate_path(download->GetFullPath()); + ASSERT_FALSE(intermediate_path.empty()); + EXPECT_TRUE(file_util::PathExists(intermediate_path)); + + download->Remove(); + RunAllPendingInMessageLoop(BrowserThread::FILE); + RunAllPendingInMessageLoop(); + + // The intermediate file should now be gone. + EXPECT_FALSE(file_util::PathExists(intermediate_path)); + } + + // A completed download shouldn't delete the downloaded file when it is + // removed. + { + // Start the second download and wait until it's done. + base::FilePath file2(FILE_PATH_LITERAL("download-test.lib")); + GURL url2(URLRequestMockHTTPJob::GetMockUrl(file2)); + scoped_ptr<DownloadTestObserver> completion_observer( + CreateWaiter(shell(), 1)); + DownloadItem* download(StartDownloadAndReturnItem(url2)); + completion_observer->WaitForFinished(); + + // The target path should exist. + base::FilePath target_path(download->GetTargetFilePath()); + EXPECT_TRUE(file_util::PathExists(target_path)); + download->Remove(); + RunAllPendingInMessageLoop(BrowserThread::FILE); + RunAllPendingInMessageLoop(); + + // The file should still exist. + EXPECT_TRUE(file_util::PathExists(target_path)); + } +} + +IN_PROC_BROWSER_TEST_F(DownloadContentTest, RemoveResumingDownload) { + SetupEnsureNoPendingDownloads(); + CommandLine::ForCurrentProcess()->AppendSwitch( + switches::kEnableDownloadResumption); + ASSERT_TRUE(test_server()->Start()); + + GURL url = test_server()->GetURL( + base::StringPrintf("rangereset?size=%d&rst_boundary=%d", + GetSafeBufferChunk() * 3, GetSafeBufferChunk())); + + MockDownloadManagerObserver dm_observer(DownloadManagerForShell(shell())); + EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(1); + + DownloadItem* download(StartDownloadAndReturnItem(url)); + WaitForData(download, GetSafeBufferChunk()); + ::testing::Mock::VerifyAndClearExpectations(&dm_observer); + + // Tell the server to send the RST and confirm the interrupt happens. + ReleaseRSTAndConfirmInterruptForResume(download); + ConfirmFileStatusForResume( + download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3, + base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload"))); + + base::FilePath intermediate_path(download->GetFullPath()); + ASSERT_FALSE(intermediate_path.empty()); + EXPECT_TRUE(file_util::PathExists(intermediate_path)); + + // Resume and remove download. We expect only a single OnDownloadCreated() + // call, and that's for the second download created below. + EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(1); + download->Resume(); + download->Remove(); + + // The intermediate file should now be gone. + RunAllPendingInMessageLoop(BrowserThread::FILE); + RunAllPendingInMessageLoop(); + EXPECT_FALSE(file_util::PathExists(intermediate_path)); + + // Start the second download and wait until it's done. The test server is + // single threaded. The response to this download request should follow the + // response to the previous resumption request. + GURL url2(test_server()->GetURL("rangereset?size=100&rst_limit=0&token=x")); + DownloadAndWait(shell(), url2, DownloadItem::COMPLETE); + + EXPECT_TRUE(EnsureNoPendingDownloads()); +} + +IN_PROC_BROWSER_TEST_F(DownloadContentTest, CancelResumingDownload) { + SetupEnsureNoPendingDownloads(); + CommandLine::ForCurrentProcess()->AppendSwitch( + switches::kEnableDownloadResumption); + ASSERT_TRUE(test_server()->Start()); + + GURL url = test_server()->GetURL( + base::StringPrintf("rangereset?size=%d&rst_boundary=%d", + GetSafeBufferChunk() * 3, GetSafeBufferChunk())); + + MockDownloadManagerObserver dm_observer(DownloadManagerForShell(shell())); + EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(1); + + DownloadItem* download(StartDownloadAndReturnItem(url)); + WaitForData(download, GetSafeBufferChunk()); + ::testing::Mock::VerifyAndClearExpectations(&dm_observer); + + // Tell the server to send the RST and confirm the interrupt happens. + ReleaseRSTAndConfirmInterruptForResume(download); + ConfirmFileStatusForResume( + download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3, + base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload"))); + + base::FilePath intermediate_path(download->GetFullPath()); + ASSERT_FALSE(intermediate_path.empty()); + EXPECT_TRUE(file_util::PathExists(intermediate_path)); + + // Resume and cancel download. We expect only a single OnDownloadCreated() + // call, and that's for the second download created below. + EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(1); + download->Resume(); + download->Cancel(DownloadItem::DELETE_DUE_TO_USER_DISCARD); + + // The intermediate file should now be gone. + RunAllPendingInMessageLoop(BrowserThread::FILE); + RunAllPendingInMessageLoop(); + EXPECT_FALSE(file_util::PathExists(intermediate_path)); + EXPECT_TRUE(download->GetFullPath().empty()); + + // Start the second download and wait until it's done. The test server is + // single threaded. The response to this download request should follow the + // response to the previous resumption request. + GURL url2(test_server()->GetURL("rangereset?size=100&rst_limit=0&token=x")); + DownloadAndWait(shell(), url2, DownloadItem::COMPLETE); + + EXPECT_TRUE(EnsureNoPendingDownloads()); +} + } // namespace content diff --git a/content/browser/download/download_id_unittest.cc b/content/browser/download/download_id_unittest.cc index ad84c91a66..8b014bfbe7 100644 --- a/content/browser/download/download_id_unittest.cc +++ b/content/browser/download/download_id_unittest.cc @@ -9,7 +9,7 @@ #include <set> #include <vector> -#include "base/memory/scoped_ptr.h" +#include "base/memory/scoped_vector.h" #include "content/browser/browser_thread_impl.h" #include "content/public/test/mock_download_manager.h" #include "testing/gtest/include/gtest/gtest.h" @@ -20,34 +20,22 @@ class DownloadIdTest : public testing::Test { public: DownloadIdTest() : ui_thread_(BrowserThread::UI, &message_loop_) { - num_managers_ = ARRAYSIZE_UNSAFE(download_managers_); - std::vector<MockDownloadManager*> managers; - managers.resize(num_managers_); - size_t i; - // Create the download managers. - for (i = 0; i < num_managers_; ++i) { - managers[i] = new MockDownloadManager(); + const size_t num_managers_ = 2; + for (size_t i = 0; i < num_managers_; ++i) { + download_managers_.push_back(new MockDownloadManager()); } - // Sort by pointer value. - std::sort(managers.begin(), managers.end()); - // Assign to |download_managers_|. - for (i = 0; i < num_managers_; ++i) { - download_managers_[i] = managers[i]; - managers[i] = NULL; - } - } - virtual ~DownloadIdTest() { - for (size_t i = 0; i < num_managers_; ++i) - download_managers_[i] = NULL; // Releases & deletes. + // These pointers will be used as Domains for DownloadIds. Domain affects + // the comparison of two DownloadIds, so we keep them sorted and use + // that property when testing. + std::sort(download_managers_.begin(), download_managers_.end()); } protected: - scoped_refptr<DownloadManager> download_managers_[2]; + ScopedVector<DownloadManager> download_managers_; base::MessageLoopForUI message_loop_; // Necessary to delete |DownloadManager|s. BrowserThreadImpl ui_thread_; - size_t num_managers_; DISALLOW_COPY_AND_ASSIGN(DownloadIdTest); }; @@ -89,7 +77,7 @@ TEST_F(DownloadIdTest, NotEqualsIndex) { TEST_F(DownloadIdTest, NotEqualsManager) { // Because it's sorted above, &download_managers_[1] > &download_managers_[0]. - EXPECT_LT(download_managers_[0].get(), download_managers_[1].get()); + EXPECT_LT(download_managers_[0], download_managers_[1]); DownloadId id1(download_managers_[0], 23); DownloadId id2(download_managers_[1], 23); DownloadId id3(download_managers_[1], 22); diff --git a/content/browser/download/download_item_impl.cc b/content/browser/download/download_item_impl.cc index 1413393f00..e2bf57a2c0 100644 --- a/content/browser/download/download_item_impl.cc +++ b/content/browser/download/download_item_impl.cc @@ -78,6 +78,11 @@ static void DownloadFileCancel(scoped_ptr<DownloadFile> download_file) { download_file->Cancel(); } +bool IsDownloadResumptionEnabled() { + return CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableDownloadResumption); +} + } // namespace const char DownloadItem::kEmptyFileHash[] = ""; @@ -309,33 +314,39 @@ void DownloadItemImpl::Pause() { void DownloadItemImpl::Resume() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + switch (state_) { + case IN_PROGRESS_INTERNAL: + if (!is_paused_) + return; + request_handle_->ResumeRequest(); + is_paused_ = false; + UpdateObservers(); + return; - // Ignore irrelevant states. - if (state_ == COMPLETE_INTERNAL || - state_ == COMPLETING_INTERNAL || - state_ == CANCELLED_INTERNAL || - (state_ == IN_PROGRESS_INTERNAL && !is_paused_)) - return; + case COMPLETING_INTERNAL: + case COMPLETE_INTERNAL: + case CANCELLED_INTERNAL: + case RESUMING_INTERNAL: + return; - if (state_ == INTERRUPTED_INTERNAL) { - auto_resume_count_ = 0; // User input resets the counter. - ResumeInterruptedDownload(); - return; - } - DCHECK_EQ(IN_PROGRESS_INTERNAL, state_); + case INTERRUPTED_INTERNAL: + auto_resume_count_ = 0; // User input resets the counter. + ResumeInterruptedDownload(); + return; - request_handle_->ResumeRequest(); - is_paused_ = false; - UpdateObservers(); + case MAX_DOWNLOAD_INTERNAL_STATE: + NOTREACHED(); + } } void DownloadItemImpl::Cancel(bool user_cancel) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); VLOG(20) << __FUNCTION__ << "() download = " << DebugString(true); - if (state_ != IN_PROGRESS_INTERNAL && state_ != INTERRUPTED_INTERNAL) { - // Small downloads might be complete before this method has - // a chance to run. + if (state_ != IN_PROGRESS_INTERNAL && + state_ != INTERRUPTED_INTERNAL && + state_ != RESUMING_INTERNAL) { + // Small downloads might be complete before this method has a chance to run. return; } @@ -352,12 +363,21 @@ void DownloadItemImpl::Cancel(bool user_cancel) { if (!is_save_package_download_ && download_file_) ReleaseDownloadFile(true); - if (state_ != INTERRUPTED_INTERNAL) { + if (state_ == IN_PROGRESS_INTERNAL) { // Cancel the originating URL request unless it's already been cancelled // by interrupt. request_handle_->CancelRequest(); } + // Remove the intermediate file if we are cancelling an interrupted download. + // Continuable interruptions leave the intermediate file around. + if ((state_ == INTERRUPTED_INTERNAL || state_ == RESUMING_INTERNAL) && + !current_path_.empty()) { + BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, + base::Bind(&DeleteDownloadedFile, current_path_)); + current_path_.clear(); + } + TransitionTo(CANCELLED_INTERNAL); } @@ -395,15 +415,6 @@ void DownloadItemImpl::Remove() { VLOG(20) << __FUNCTION__ << "() download = " << DebugString(true); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - // Remove the intermediate file if we are removing an interrupted download. - // Continuable interruptions leave the intermediate file around. However, the - // intermediate file will be unusable if the download item is removed. - if (!current_path_.empty() && IsInterrupted() && !download_file_.get()) { - BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, - base::Bind(&DeleteDownloadedFile, current_path_)); - current_path_.clear(); - } - delegate_->AssertStateConsistent(this); Cancel(true); delegate_->AssertStateConsistent(this); @@ -468,6 +479,24 @@ bool DownloadItemImpl::IsTemporary() const { return is_temporary_; } +bool DownloadItemImpl::CanResume() const { + if (IsInProgress() && IsPaused()) + return true; + + if (state_ != INTERRUPTED_INTERNAL) + return false; + + // Downloads that don't have a WebContents should still be resumable, but this + // isn't currently the case. See ResumeInterruptedDownload(). + if (!GetWebContents()) + return false; + + ResumeMode resume_mode = GetResumeMode(); + return IsDownloadResumptionEnabled() && + (resume_mode == RESUME_MODE_USER_RESTART || + resume_mode == RESUME_MODE_USER_CONTINUE); +} + // TODO(rdsmith): Figure out whether or not we want this probe routine // to consider interrupted (resumably) downloads partial downloads. // Conceptually the answer is probably yes, but everywhere that currently @@ -565,13 +594,6 @@ const base::FilePath& DownloadItemImpl::GetForcedFilePath() const { return forced_file_path_; } -// TODO(asanka): Get rid of GetUserVerifiedFilePath(). http://crbug.com/134237. -base::FilePath DownloadItemImpl::GetUserVerifiedFilePath() const { - return (IsDangerous() || - danger_type_ == DOWNLOAD_DANGER_TYPE_USER_VALIDATED) ? - GetFullPath() : GetTargetFilePath(); -} - base::FilePath DownloadItemImpl::GetFileNameToReportUser() const { if (!display_name_.empty()) return display_name_; @@ -676,7 +698,7 @@ bool DownloadItemImpl::CanOpenDownload() { } bool DownloadItemImpl::ShouldOpenFileBasedOnExtension() { - return delegate_->ShouldOpenFileBasedOnExtension(GetUserVerifiedFilePath()); + return delegate_->ShouldOpenFileBasedOnExtension(GetTargetFilePath()); } bool DownloadItemImpl::GetOpenWhenComplete() const { @@ -883,46 +905,6 @@ void DownloadItemImpl::SetTotalBytes(int64 total_bytes) { total_bytes_ = total_bytes; } -// Updates from the download thread may have been posted while this download -// was being cancelled in the UI thread, so we'll accept them unless we're -// complete. -void DownloadItemImpl::UpdateProgress(int64 bytes_so_far, - int64 bytes_per_sec, - const std::string& hash_state) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - VLOG(20) << __FUNCTION__ << " so_far=" << bytes_so_far - << " per_sec=" << bytes_per_sec << " download=" << DebugString(true); - - if (state_ != IN_PROGRESS_INTERNAL) { - // Ignore if we're no longer in-progress. This can happen if we race a - // Cancel on the UI thread with an update on the FILE thread. - // - // TODO(rdsmith): Arguably we should let this go through, as this means - // the download really did get further than we know before it was - // cancelled. But the gain isn't very large, and the code is more - // fragile if it has to support in progress updates in a non-in-progress - // state. This issue should be readdressed when we revamp performance - // reporting. - return; - } - bytes_per_sec_ = bytes_per_sec; - hash_state_ = hash_state; - received_bytes_ = bytes_so_far; - - // If we've received more data than we were expecting (bad server info?), - // revert to 'unknown size mode'. - if (received_bytes_ > total_bytes_) - total_bytes_ = 0; - - if (bound_net_log_.IsLoggingAllEvents()) { - bound_net_log_.AddEvent( - net::NetLog::TYPE_DOWNLOAD_ITEM_UPDATED, - net::NetLog::Int64Callback("bytes_so_far", received_bytes_)); - } - - UpdateObservers(); -} - void DownloadItemImpl::OnAllDataSaved(const std::string& final_hash) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); @@ -949,7 +931,8 @@ void DownloadItemImpl::DestinationUpdate(int64 bytes_so_far, int64 bytes_per_sec, const std::string& hash_state) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - VLOG(20) << __FUNCTION__ << " download=" << DebugString(true); + VLOG(20) << __FUNCTION__ << " so_far=" << bytes_so_far + << " per_sec=" << bytes_per_sec << " download=" << DebugString(true); if (!IsInProgress()) { // Ignore if we're no longer in-progress. This can happen if we race a @@ -1048,6 +1031,14 @@ void DownloadItemImpl::Start( download_file_ = file.Pass(); request_handle_ = req_handle.Pass(); + if (IsCancelled()) { + // The download was in the process of resuming when it was cancelled. Don't + // proceed. + ReleaseDownloadFile(true); + request_handle_->CancelRequest(); + return; + } + TransitionTo(IN_PROGRESS_INTERNAL); last_reason_ = DOWNLOAD_INTERRUPT_REASON_NONE; @@ -1326,6 +1317,25 @@ void DownloadItemImpl::Completed() { } } +void DownloadItemImpl::OnResumeRequestStarted(DownloadItem* item, + net::Error error) { + // If |item| is not NULL, then Start() has been called already, and nothing + // more needs to be done here. + if (item) { + DCHECK_EQ(net::OK, error); + DCHECK_EQ(static_cast<DownloadItem*>(this), item); + return; + } + // Otherwise, the request failed without passing through + // DownloadResourceHandler::OnResponseStarted. + if (error == net::OK) + error = net::ERR_FAILED; + DownloadInterruptReason reason = + ConvertNetErrorToInterruptReason(error, DOWNLOAD_INTERRUPT_FROM_NETWORK); + DCHECK_NE(DOWNLOAD_INTERRUPT_REASON_NONE, reason); + Interrupt(reason); +} + // **** End of Download progression cascade // An error occurred somewhere. @@ -1342,7 +1352,7 @@ void DownloadItemImpl::Interrupt(DownloadInterruptReason reason) { // interrupts to race with cancels. // Whatever happens, the first one to hit the UI thread wins. - if (state_ != IN_PROGRESS_INTERNAL) + if (state_ != IN_PROGRESS_INTERNAL && state_ != RESUMING_INTERNAL) return; last_reason_ = reason; @@ -1351,11 +1361,9 @@ void DownloadItemImpl::Interrupt(DownloadInterruptReason reason) { // Cancel (delete file) if we're going to restart; no point in leaving // data around we aren't going to use. Also cancel if resumption isn't // enabled for the same reason. - bool resumption_enabled = CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableDownloadResumption); ReleaseDownloadFile(resume_mode == RESUME_MODE_IMMEDIATE_RESTART || resume_mode == RESUME_MODE_USER_RESTART || - !resumption_enabled); + !IsDownloadResumptionEnabled()); // Reset all data saved, as even if we did save all the data we're going // to go through another round of downloading when we resume. @@ -1555,7 +1563,7 @@ void DownloadItemImpl::ResumeInterruptedDownload() { return; // If we're not interrupted, ignore the request; our caller is drunk. - if (!IsInterrupted()) + if (state_ != INTERRUPTED_INTERNAL) return; // If we can't get a web contents, we can't resume the download. @@ -1584,11 +1592,15 @@ void DownloadItemImpl::ResumeInterruptedDownload() { download_params->set_hash_state(GetHashState()); download_params->set_last_modified(GetLastModifiedTime()); download_params->set_etag(GetETag()); + download_params->set_callback( + base::Bind(&DownloadItemImpl::OnResumeRequestStarted, + weak_ptr_factory_.GetWeakPtr())); delegate_->ResumeInterruptedDownload(download_params.Pass(), GetGlobalId()); - // Just in case we were interrupted while paused. is_paused_ = false; + + TransitionTo(RESUMING_INTERNAL); } // static @@ -1605,30 +1617,33 @@ DownloadItem::DownloadState DownloadItemImpl::InternalToExternalState( return CANCELLED; case INTERRUPTED_INTERNAL: return INTERRUPTED; - default: - NOTREACHED(); + case RESUMING_INTERNAL: + return INTERRUPTED; + case MAX_DOWNLOAD_INTERNAL_STATE: + break; } + NOTREACHED(); return MAX_DOWNLOAD_STATE; } // static DownloadItemImpl::DownloadInternalState DownloadItemImpl::ExternalToInternalState( - DownloadState external_state) { - switch (external_state) { - case IN_PROGRESS: - return IN_PROGRESS_INTERNAL; - case COMPLETE: - return COMPLETE_INTERNAL; - case CANCELLED: - return CANCELLED_INTERNAL; - case INTERRUPTED: - return INTERRUPTED_INTERNAL; - default: - NOTREACHED(); - } - return MAX_DOWNLOAD_INTERNAL_STATE; - } + DownloadState external_state) { + switch (external_state) { + case IN_PROGRESS: + return IN_PROGRESS_INTERNAL; + case COMPLETE: + return COMPLETE_INTERNAL; + case CANCELLED: + return CANCELLED_INTERNAL; + case INTERRUPTED: + return INTERRUPTED_INTERNAL; + default: + NOTREACHED(); + } + return MAX_DOWNLOAD_INTERNAL_STATE; +} const char* DownloadItemImpl::DebugDownloadStateString( DownloadInternalState state) { @@ -1643,10 +1658,13 @@ const char* DownloadItemImpl::DebugDownloadStateString( return "CANCELLED"; case INTERRUPTED_INTERNAL: return "INTERRUPTED"; - default: - NOTREACHED() << "Unknown download state " << state; - return "unknown"; + case RESUMING_INTERNAL: + return "RESUMING"; + case MAX_DOWNLOAD_INTERNAL_STATE: + break; }; + NOTREACHED() << "Unknown download state " << state; + return "unknown"; } const char* DownloadItemImpl::DebugResumeModeString(ResumeMode mode) { diff --git a/content/browser/download/download_item_impl.h b/content/browser/download/download_item_impl.h index 083a1591ab..0acc83022b 100644 --- a/content/browser/download/download_item_impl.h +++ b/content/browser/download/download_item_impl.h @@ -104,6 +104,7 @@ class CONTENT_EXPORT DownloadItemImpl virtual DownloadInterruptReason GetLastReason() const OVERRIDE; virtual bool IsPaused() const OVERRIDE; virtual bool IsTemporary() const OVERRIDE; + virtual bool CanResume() const OVERRIDE; virtual bool IsPartialDownload() const OVERRIDE; virtual bool IsInProgress() const OVERRIDE; virtual bool IsCancelled() const OVERRIDE; @@ -126,7 +127,6 @@ class CONTENT_EXPORT DownloadItemImpl virtual const base::FilePath& GetFullPath() const OVERRIDE; virtual const base::FilePath& GetTargetFilePath() const OVERRIDE; virtual const base::FilePath& GetForcedFilePath() const OVERRIDE; - virtual base::FilePath GetUserVerifiedFilePath() const OVERRIDE; virtual base::FilePath GetFileNameToReportUser() const OVERRIDE; virtual TargetDisposition GetTargetDisposition() const OVERRIDE; virtual const std::string& GetHash() const OVERRIDE; @@ -196,57 +196,89 @@ class CONTENT_EXPORT DownloadItemImpl // Called by SavePackage to set the total number of bytes on the item. virtual void SetTotalBytes(int64 total_bytes); - // Indicate progress in saving data to its destination. - // |bytes_so_far| is the number of bytes received so far. - // |hash_state| is the current hash state. - virtual void UpdateProgress(int64 bytes_so_far, - int64 bytes_per_sec, - const std::string& hash_state); - virtual void OnAllDataSaved(const std::string& final_hash); // Called by SavePackage to display progress when the DownloadItem // should be considered complete. virtual void MarkAsComplete(); + // DownloadDestinationObserver + virtual void DestinationUpdate(int64 bytes_so_far, + int64 bytes_per_sec, + const std::string& hash_state) OVERRIDE; + virtual void DestinationError(DownloadInterruptReason reason) OVERRIDE; + virtual void DestinationCompleted(const std::string& final_hash) OVERRIDE; + private: - // Fine grained states of a download. - enum DownloadInternalState { - // Unless otherwise specified, state transitions are linear forward - // in this list. + // Fine grained states of a download. Note that active downloads are created + // in IN_PROGRESS_INTERNAL state. However, downloads creates via history can + // be created in COMPLETE_INTERNAL, CANCELLED_INTERNAL and + // INTERRUPTED_INTERNAL. - // Includes both before and after file name determination. + enum DownloadInternalState { + // Includes both before and after file name determination, and paused + // downloads. // TODO(rdsmith): Put in state variable for file name determination. + // Transitions from: + // <Initial creation> Active downloads are created in this state. + // RESUMING_INTERNAL + // Transitions to: + // COMPLETING_INTERNAL On final rename completion. + // CANCELLED_INTERNAL On cancel. + // INTERRUPTED_INTERNAL On interrupt. + // COMPLETE_INTERNAL On SavePackage download completion. IN_PROGRESS_INTERNAL, // Between commit point (dispatch of download file release) and completed. - // Embedder may be opening the file in this state. Note that the - // DownloadItem may be deleted (by shutdown) or interrupted (e.g. due to a - // failure during AnnotateWithSourceInformation()) in this state. + // Embedder may be opening the file in this state. + // Transitions from: + // IN_PROGRESS_INTERNAL + // Transitions to: + // COMPLETE_INTERNAL On successful completion. COMPLETING_INTERNAL, // After embedder has had a chance to auto-open. User may now open // or auto-open based on extension. + // Transitions from: + // COMPLETING_INTERNAL + // IN_PROGRESS_INTERNAL SavePackage only. + // <Initial creation> Completed persisted downloads. + // Transitions to: + // <none> Terminal state. COMPLETE_INTERNAL, // User has cancelled the download. - // Only incoming transition IN_PROGRESS-> + // Transitions from: + // IN_PROGRESS_INTERNAL + // INTERRUPTED_INTERNAL + // RESUMING_INTERNAL + // <Initial creation> Canceleld persisted downloads. + // Transitions to: + // <none> Terminal state. CANCELLED_INTERNAL, // An error has interrupted the download. - // Only incoming transition IN_PROGRESS-> + // Transitions from: + // IN_PROGRESS_INTERNAL + // RESUMING_INTERNAL + // <Initial creation> Interrupted persisted downloads. + // Transitions to: + // RESUMING_INTERNAL On resumption. INTERRUPTED_INTERNAL, + // A request to resume this interrupted download is in progress. + // Transitions from: + // INTERRUPTED_INTERNAL + // Transitions to: + // IN_PROGRESS_INTERNAL Once a server response is received from a + // resumption. + // INTERRUPTED_INTERNAL If the resumption request fails. + // CANCELLED_INTERNAL On cancel. + RESUMING_INTERNAL, + MAX_DOWNLOAD_INTERNAL_STATE, }; - // DownloadDestinationObserver - virtual void DestinationUpdate(int64 bytes_so_far, - int64 bytes_per_sec, - const std::string& hash_state) OVERRIDE; - virtual void DestinationError(DownloadInterruptReason reason) OVERRIDE; - virtual void DestinationCompleted(const std::string& final_hash) OVERRIDE; - // Normal progression of a download ------------------------------------------ // These are listed in approximately chronological order. There are also @@ -297,6 +329,9 @@ class CONTENT_EXPORT DownloadItemImpl // is completed. void Completed(); + // Callback invoked when the URLRequest for a download resumption has started. + void OnResumeRequestStarted(DownloadItem* item, net::Error error); + // Helper routines ----------------------------------------------------------- // Indicate that an error has occurred on the download. diff --git a/content/browser/download/download_item_impl_unittest.cc b/content/browser/download/download_item_impl_unittest.cc index 7a29f28e71..fab8e996c7 100644 --- a/content/browser/download/download_item_impl_unittest.cc +++ b/content/browser/download/download_item_impl_unittest.cc @@ -344,7 +344,7 @@ TEST_F(DownloadItemTest, NotificationAfterUpdate) { DownloadItemImpl* item = CreateDownloadItem(); MockObserver observer(item); - item->UpdateProgress(kDownloadChunkSize, kDownloadSpeed, std::string()); + item->DestinationUpdate(kDownloadChunkSize, kDownloadSpeed, std::string()); ASSERT_TRUE(observer.CheckUpdated()); EXPECT_EQ(kDownloadSpeed, item->CurrentSpeed()); } diff --git a/content/browser/download/download_manager_impl.cc b/content/browser/download/download_manager_impl.cc index 3fa90438b7..16d1b29a62 100644 --- a/content/browser/download/download_manager_impl.cc +++ b/content/browser/download/download_manager_impl.cc @@ -239,7 +239,8 @@ DownloadManagerImpl::DownloadManagerImpl( shutdown_needed_(true), browser_context_(browser_context), delegate_(NULL), - net_log_(net_log) { + net_log_(net_log), + weak_factory_(this) { DCHECK(browser_context); } @@ -247,12 +248,14 @@ DownloadManagerImpl::~DownloadManagerImpl() { DCHECK(!shutdown_needed_); } -void DownloadManagerImpl::CreateActiveItem( +DownloadItemImpl* DownloadManagerImpl::CreateActiveItem( DownloadId id, const DownloadCreateInfo& info) { net::BoundNetLog bound_net_log = net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); - downloads_[id.local()] = + DownloadItemImpl* download = item_factory_->CreateActiveItem(this, id, info, bound_net_log); + downloads_[id.local()] = download; + return download; } DownloadId DownloadManagerImpl::GetNextId() { @@ -377,6 +380,28 @@ DownloadItem* DownloadManagerImpl::StartDownload( scoped_ptr<ByteStreamReader> stream) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + DownloadId id(info->download_id); + const bool new_download = !id.IsValid(); + DownloadItemImpl* download = NULL; + + if (new_download) { + id = GetNextId(); + download = CreateActiveItem(id, *info); + } else { + DownloadMap::iterator item_iterator = downloads_.find(id.local()); + // Trying to resume an interrupted download. + if (item_iterator == downloads_.end() || + item_iterator->second->IsCancelled()) { + // If the download is no longer known to the DownloadManager, then it was + // removed after it was resumed. Ignore. If the download is cancelled + // while resuming, then also ignore the request. + info->request_handle.CancelRequest(); + return NULL; + } + download = item_iterator->second; + DCHECK(download->IsInterrupted()); + } + base::FilePath default_download_directory; if (delegate_) { base::FilePath website_save_directory; // Unused @@ -385,20 +410,6 @@ DownloadItem* DownloadManagerImpl::StartDownload( &default_download_directory, &skip_dir_check); } - // If we don't have a valid id, that's a signal to generate one. - DownloadId id(info->download_id); - if (!id.IsValid()) - id = GetNextId(); - - // Create a new download item if this isn't a resumption. - bool new_download(!ContainsKey(downloads_, id.local())); - if (new_download) - CreateActiveItem(id, *info); - - DownloadItemImpl* download(downloads_[id.local()]); - DCHECK(download); - DCHECK(new_download || download->IsInterrupted()); - // Create the download file and start the download. scoped_ptr<DownloadFile> download_file( file_factory_->CreateFile( @@ -439,7 +450,7 @@ void DownloadManagerImpl::CheckForFileRemoval(DownloadItemImpl* download_item) { delegate_->CheckForFileExistence( download_item, base::Bind(&DownloadManagerImpl::OnFileExistenceChecked, - this, download_item->GetId())); + weak_factory_.GetWeakPtr(), download_item->GetId())); } } diff --git a/content/browser/download/download_manager_impl.h b/content/browser/download/download_manager_impl.h index 6885068654..7458433b48 100644 --- a/content/browser/download/download_manager_impl.h +++ b/content/browser/download/download_manager_impl.h @@ -36,6 +36,7 @@ class CONTENT_EXPORT DownloadManagerImpl : public DownloadManager, // Caller guarantees that |net_log| will remain valid // for the lifetime of DownloadManagerImpl (until Shutdown() is called). DownloadManagerImpl(net::NetLog* net_log, BrowserContext* browser_context); + virtual ~DownloadManagerImpl(); // Implementation functions (not part of the DownloadManager interface). @@ -102,13 +103,10 @@ class CONTENT_EXPORT DownloadManagerImpl : public DownloadManager, friend class DownloadManagerTest; friend class DownloadTest; - friend class base::RefCountedThreadSafe<DownloadManagerImpl>; - - virtual ~DownloadManagerImpl(); - // Create a new active item based on the info. Separate from // StartDownload() for testing. - void CreateActiveItem(DownloadId id, const DownloadCreateInfo& info); + DownloadItemImpl* CreateActiveItem(DownloadId id, + const DownloadCreateInfo& info); // Get next download id. DownloadId GetNextId(); @@ -165,6 +163,8 @@ class CONTENT_EXPORT DownloadManagerImpl : public DownloadManager, net::NetLog* net_log_; + base::WeakPtrFactory<DownloadManagerImpl> weak_factory_; + DISALLOW_COPY_AND_ASSIGN(DownloadManagerImpl); }; diff --git a/content/browser/download/download_manager_impl_unittest.cc b/content/browser/download/download_manager_impl_unittest.cc index b1e1c045bd..300eb2e0bb 100644 --- a/content/browser/download/download_manager_impl_unittest.cc +++ b/content/browser/download/download_manager_impl_unittest.cc @@ -165,7 +165,6 @@ class MockDownloadItemImpl : public DownloadItemImpl { MOCK_CONST_METHOD0(GetWebContents, WebContents*()); MOCK_CONST_METHOD0(GetFileNameToReportUser, base::FilePath()); MOCK_METHOD1(SetDisplayName, void(const base::FilePath&)); - MOCK_CONST_METHOD0(GetUserVerifiedFilePath, base::FilePath()); MOCK_METHOD0(NotifyRemoved, void()); // May be called when vlog is on. virtual std::string DebugString(bool verbose) const OVERRIDE { @@ -445,7 +444,7 @@ class DownloadManagerTest : public testing::Test { // then create a DownloadManager that points // at all of those. virtual void SetUp() { - DCHECK(!download_manager_.get()); + DCHECK(!download_manager_); mock_download_item_factory_ = (new MockDownloadItemFactory())->AsWeakPtr(); mock_download_file_factory_ = (new MockDownloadFileFactory())->AsWeakPtr(); @@ -457,8 +456,8 @@ class DownloadManagerTest : public testing::Test { EXPECT_CALL(*mock_browser_context_.get(), IsOffTheRecord()) .WillRepeatedly(Return(false)); - download_manager_ = new DownloadManagerImpl( - NULL, mock_browser_context_.get()); + download_manager_.reset(new DownloadManagerImpl( + NULL, mock_browser_context_.get())); download_manager_->SetDownloadItemFactoryForTesting( scoped_ptr<DownloadItemFactory>( mock_download_item_factory_.get()).Pass()); @@ -482,7 +481,7 @@ class DownloadManagerTest : public testing::Test { .WillOnce(Return()); download_manager_->Shutdown(); - download_manager_ = NULL; + download_manager_.reset(); message_loop_.RunUntilIdle(); ASSERT_EQ(NULL, mock_download_item_factory_.get()); ASSERT_EQ(NULL, mock_download_file_factory_.get()); @@ -556,7 +555,7 @@ class DownloadManagerTest : public testing::Test { protected: // Key test variable; we'll keep it available to sub-classes. - scoped_refptr<DownloadManagerImpl> download_manager_; + scoped_ptr<DownloadManagerImpl> download_manager_; base::WeakPtr<MockDownloadFileFactory> mock_download_file_factory_; // Target detetermined callback. diff --git a/content/browser/download/download_resource_handler.cc b/content/browser/download/download_resource_handler.cc index 388bcd1e5a..b7cd416e4b 100644 --- a/content/browser/download/download_resource_handler.cc +++ b/content/browser/download/download_resource_handler.cc @@ -65,8 +65,9 @@ static void StartOnUIThread( DownloadItem* item = download_manager->StartDownload( info.Pass(), stream.Pass()); + // |item| can be NULL if the download has been removed. if (!started_cb.is_null()) - started_cb.Run(item, net::OK); + started_cb.Run(item, item ? net::OK : net::ERR_ABORTED); } } // namespace @@ -102,7 +103,6 @@ bool DownloadResourceHandler::OnUploadProgress(int request_id, return true; } -// Not needed, as this event handler ought to be the final resource. bool DownloadResourceHandler::OnRequestRedirected( int request_id, const GURL& url, @@ -128,6 +128,10 @@ bool DownloadResourceHandler::OnResponseStarted( // If it's a download, we don't want to poison the cache with it. request_->StopCaching(); + // Lower priority as well, so downloads don't contend for resources + // with main frames. + request_->SetPriority(net::IDLE); + std::string content_disposition; request_->GetResponseHeaderByName("content-disposition", &content_disposition); diff --git a/content/browser/download/mhtml_generation_browsertest.cc b/content/browser/download/mhtml_generation_browsertest.cc index e8a90424c3..07bffed6b4 100644 --- a/content/browser/download/mhtml_generation_browsertest.cc +++ b/content/browser/download/mhtml_generation_browsertest.cc @@ -12,7 +12,7 @@ #include "content/shell/shell.h" #include "content/test/content_browser_test.h" #include "content/test/content_browser_test_utils.h" -#include "net/test/spawned_test_server/spawned_test_server.h" +#include "net/test/embedded_test_server/embedded_test_server.h" #include "testing/gtest/include/gtest/gtest.h" namespace content { @@ -48,12 +48,12 @@ class MHTMLGenerationTest : public ContentBrowserTest { // test is to ensure we were successfull in creating the MHTML data from the // renderer. IN_PROC_BROWSER_TEST_F(MHTMLGenerationTest, GenerateMHTML) { - ASSERT_TRUE(test_server()->Start()); + ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); base::FilePath path(temp_dir_.path()); path = path.Append(FILE_PATH_LITERAL("test.mht")); - NavigateToURL(shell(), test_server()->GetURL("files/simple_page.html")); + NavigateToURL(shell(), embedded_test_server()->GetURL("/simple_page.html")); shell()->web_contents()->GenerateMHTML( path, base::Bind(&MHTMLGenerationTest::MHTMLGenerated, this)); diff --git a/content/browser/download/save_package.cc b/content/browser/download/save_package.cc index 7553a54f77..9bbe1662da 100644 --- a/content/browser/download/save_package.cc +++ b/content/browser/download/save_package.cc @@ -365,7 +365,7 @@ void SavePackage::OnMHTMLGenerated(const base::FilePath& path, int64 size) { // with SavePackage flow. if (download_->IsInProgress()) { download_->SetTotalBytes(size); - download_->UpdateProgress(size, 0, std::string()); + download_->DestinationUpdate(size, 0, std::string()); // Must call OnAllDataSaved here in order for // GDataDownloadObserver::ShouldUpload() to return true. // ShouldCompleteDownload() may depend on the gdata uploader to finish. @@ -792,7 +792,7 @@ void SavePackage::Finish() { // with SavePackage flow. if (download_->IsInProgress()) { if (save_type_ != SAVE_PAGE_TYPE_AS_MHTML) { - download_->UpdateProgress( + download_->DestinationUpdate( all_save_items_count_, CurrentSpeed(), std::string()); download_->OnAllDataSaved(DownloadItem::kEmptyFileHash); } @@ -822,8 +822,10 @@ void SavePackage::SaveFinished(int32 save_id, int64 size, bool is_success) { // Hack to avoid touching download_ after user cancel. // TODO(rdsmith/benjhayden): Integrate canceling on DownloadItem // with SavePackage flow. - if (download_ && download_->IsInProgress()) - download_->UpdateProgress(completed_count(), CurrentSpeed(), std::string()); + if (download_ && download_->IsInProgress()) { + download_->DestinationUpdate( + completed_count(), CurrentSpeed(), std::string()); + } if (save_item->save_source() == SaveFileCreateInfo::SAVE_FILE_FROM_DOM && save_item->url() == page_url_ && !save_item->received_bytes()) { @@ -867,8 +869,10 @@ void SavePackage::SaveFailed(const GURL& save_url) { // Hack to avoid touching download_ after user cancel. // TODO(rdsmith/benjhayden): Integrate canceling on DownloadItem // with SavePackage flow. - if (download_ && download_->IsInProgress()) - download_->UpdateProgress(completed_count(), CurrentSpeed(), std::string()); + if (download_ && download_->IsInProgress()) { + download_->DestinationUpdate( + completed_count(), CurrentSpeed(), std::string()); + } if ((save_type_ == SAVE_PAGE_TYPE_AS_ONLY_HTML) || (save_type_ == SAVE_PAGE_TYPE_AS_MHTML) || diff --git a/content/browser/fileapi/browser_file_system_helper.cc b/content/browser/fileapi/browser_file_system_helper.cc index 75a8aae7f0..b7b8945a29 100644 --- a/content/browser/fileapi/browser_file_system_helper.cc +++ b/content/browser/fileapi/browser_file_system_helper.cc @@ -16,12 +16,12 @@ #include "content/public/common/content_client.h" #include "content/public/common/content_switches.h" #include "content/public/common/url_constants.h" -#include "webkit/fileapi/external_mount_points.h" -#include "webkit/fileapi/file_permission_policy.h" -#include "webkit/fileapi/file_system_options.h" -#include "webkit/fileapi/file_system_task_runners.h" -#include "webkit/fileapi/local_file_system_operation.h" -#include "webkit/fileapi/sandbox_mount_point_provider.h" +#include "webkit/browser/fileapi/external_mount_points.h" +#include "webkit/browser/fileapi/file_permission_policy.h" +#include "webkit/browser/fileapi/file_system_options.h" +#include "webkit/browser/fileapi/file_system_task_runners.h" +#include "webkit/browser/fileapi/local_file_system_operation.h" +#include "webkit/browser/fileapi/sandbox_mount_point_provider.h" #include "webkit/quota/quota_manager.h" namespace content { diff --git a/content/browser/fileapi/browser_file_system_helper.h b/content/browser/fileapi/browser_file_system_helper.h index 091a1f287f..28e5bc7c8e 100644 --- a/content/browser/fileapi/browser_file_system_helper.h +++ b/content/browser/fileapi/browser_file_system_helper.h @@ -7,7 +7,7 @@ #include "base/memory/ref_counted.h" #include "content/common/content_export.h" -#include "webkit/fileapi/file_system_context.h" +#include "webkit/browser/fileapi/file_system_context.h" namespace fileapi { class ExternalMountPoints; diff --git a/content/browser/fileapi/chrome_blob_storage_context.cc b/content/browser/fileapi/chrome_blob_storage_context.cc index 6d04408c82..6679e2c540 100644 --- a/content/browser/fileapi/chrome_blob_storage_context.cc +++ b/content/browser/fileapi/chrome_blob_storage_context.cc @@ -7,7 +7,7 @@ #include "base/bind.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" -#include "webkit/blob/blob_storage_controller.h" +#include "webkit/browser/blob/blob_storage_controller.h" using base::UserDataAdapter; using webkit_blob::BlobStorageController; diff --git a/content/browser/fileapi/file_system_browsertest.cc b/content/browser/fileapi/file_system_browsertest.cc index d8e55affe1..510064f9ed 100644 --- a/content/browser/fileapi/file_system_browsertest.cc +++ b/content/browser/fileapi/file_system_browsertest.cc @@ -17,7 +17,6 @@ #include "content/test/content_browser_test.h" #include "content/test/content_browser_test_utils.h" #include "content/test/layout_browsertest.h" -#include "net/test/spawned_test_server/spawned_test_server.h" #include "webkit/quota/quota_manager.h" using quota::QuotaManager; diff --git a/content/browser/fileapi/fileapi_message_filter.cc b/content/browser/fileapi/fileapi_message_filter.cc index 966490eb7d..0ec6a0c023 100644 --- a/content/browser/fileapi/fileapi_message_filter.cc +++ b/content/browser/fileapi/fileapi_message_filter.cc @@ -24,17 +24,18 @@ #include "net/base/mime_util.h" #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context_getter.h" -#include "webkit/blob/blob_data.h" -#include "webkit/blob/blob_storage_controller.h" -#include "webkit/blob/shareable_file_reference.h" -#include "webkit/fileapi/file_observers.h" -#include "webkit/fileapi/file_permission_policy.h" -#include "webkit/fileapi/file_system_context.h" -#include "webkit/fileapi/file_system_types.h" -#include "webkit/fileapi/file_system_util.h" -#include "webkit/fileapi/isolated_context.h" -#include "webkit/fileapi/local_file_system_operation.h" -#include "webkit/fileapi/sandbox_mount_point_provider.h" +#include "webkit/browser/blob/blob_storage_controller.h" +#include "webkit/browser/fileapi/file_observers.h" +#include "webkit/browser/fileapi/file_permission_policy.h" +#include "webkit/browser/fileapi/file_system_context.h" +#include "webkit/browser/fileapi/isolated_context.h" +#include "webkit/browser/fileapi/local_file_system_operation.h" +#include "webkit/browser/fileapi/sandbox_mount_point_provider.h" +#include "webkit/common/blob/blob_data.h" +#include "webkit/common/blob/shareable_file_reference.h" +#include "webkit/common/fileapi/directory_entry.h" +#include "webkit/common/fileapi/file_system_types.h" +#include "webkit/common/fileapi/file_system_util.h" #include "webkit/quota/quota_manager.h" using fileapi::FileSystemFileUtil; @@ -194,7 +195,11 @@ void FileAPIMessageFilter::OnOpen( } else if (type == fileapi::kFileSystemTypePersistent) { RecordAction(UserMetricsAction("OpenFileSystemPersistent")); } - context_->OpenFileSystem(origin_url, type, create, base::Bind( + // TODO(kinuko): Use this mode for IPC too. + fileapi::OpenFileSystemMode mode = + create ? fileapi::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT + : fileapi::OPEN_FILE_SYSTEM_FAIL_IF_NONEXISTENT; + context_->OpenFileSystem(origin_url, type, mode, base::Bind( &FileAPIMessageFilter::DidOpenFileSystem, this, request_id)); } @@ -650,7 +655,7 @@ void FileAPIMessageFilter::DidGetMetadata( void FileAPIMessageFilter::DidReadDirectory( int request_id, base::PlatformFileError result, - const std::vector<base::FileUtilProxy::Entry>& entries, + const std::vector<fileapi::DirectoryEntry>& entries, bool has_more) { if (result == base::PLATFORM_FILE_OK) Send(new FileSystemMsg_DidReadDirectory(request_id, entries, has_more)); @@ -748,12 +753,14 @@ void FileAPIMessageFilter::DidCreateSnapshot( // - the file comes from sandboxed filesystem. Reading sandboxed files is // always permitted, but only implicitly. // - the underlying filesystem returned newly created snapshot file. - // - the file comes from an external drive filesystem. The renderer has - // already been granted read permission for the file's nominal path, but - // for drive files, platform paths differ from the nominal paths. + // - the nominal path differs from the platform path. This can happen even + // when the filesystem has been granted permissions. This happens with: + // - Drive filesystems + // - Picasa filesystems DCHECK(snapshot_file || fileapi::SandboxMountPointProvider::IsSandboxType(url.type()) || - url.type() == fileapi::kFileSystemTypeDrive); + url.type() == fileapi::kFileSystemTypeDrive || + url.type() == fileapi::kFileSystemTypePicasa); ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadFile( process_id_, platform_path); if (snapshot_file) { diff --git a/content/browser/fileapi/fileapi_message_filter.h b/content/browser/fileapi/fileapi_message_filter.h index 99c3a1edab..d1576cd0ae 100644 --- a/content/browser/fileapi/fileapi_message_filter.h +++ b/content/browser/fileapi/fileapi_message_filter.h @@ -16,8 +16,8 @@ #include "base/platform_file.h" #include "base/shared_memory.h" #include "content/public/browser/browser_message_filter.h" -#include "webkit/blob/blob_data.h" -#include "webkit/fileapi/file_system_types.h" +#include "webkit/common/blob/blob_data.h" +#include "webkit/common/fileapi/file_system_types.h" #include "webkit/quota/quota_types.h" class GURL; @@ -31,6 +31,7 @@ namespace fileapi { class FileSystemURL; class FileSystemContext; class FileSystemOperation; +struct DirectoryEntry; } namespace net { @@ -138,7 +139,7 @@ class FileAPIMessageFilter : public BrowserMessageFilter { const base::FilePath& platform_path); void DidReadDirectory(int request_id, base::PlatformFileError result, - const std::vector<base::FileUtilProxy::Entry>& entries, + const std::vector<fileapi::DirectoryEntry>& entries, bool has_more); void DidOpenFile(int request_id, quota::QuotaLimitType quota_policy, diff --git a/content/browser/gamepad/gamepad_platform_data_fetcher_mac.h b/content/browser/gamepad/gamepad_platform_data_fetcher_mac.h index 8bcc9c2f02..e12d03c21c 100644 --- a/content/browser/gamepad/gamepad_platform_data_fetcher_mac.h +++ b/content/browser/gamepad/gamepad_platform_data_fetcher_mac.h @@ -8,10 +8,13 @@ #include "base/basictypes.h" #include "base/compiler_specific.h" #include "base/mac/scoped_cftyperef.h" +#include "base/memory/scoped_ptr.h" #include "build/build_config.h" #include "content/browser/gamepad/gamepad_data_fetcher.h" #include "content/browser/gamepad/gamepad_standard_mappings.h" +#include "content/browser/gamepad/xbox_data_fetcher_mac.h" #include "content/common/gamepad_hardware_buffer.h" +#include "third_party/WebKit/Source/Platform/chromium/public/WebGamepads.h" #include <CoreFoundation/CoreFoundation.h> #include <IOKit/hid/IOHIDManager.h> @@ -24,7 +27,8 @@ class NSArray; namespace content { -class GamepadPlatformDataFetcherMac : public GamepadDataFetcher { +class GamepadPlatformDataFetcherMac : public GamepadDataFetcher, + public XboxDataFetcher::Delegate { public: GamepadPlatformDataFetcherMac(); virtual ~GamepadPlatformDataFetcherMac(); @@ -50,27 +54,47 @@ class GamepadPlatformDataFetcherMac : public GamepadDataFetcher { void* sender, IOHIDValueRef ref); + size_t GetEmptySlot(); + size_t GetSlotForDevice(IOHIDDeviceRef device); + size_t GetSlotForXboxDevice(XboxController* device); + void DeviceAdd(IOHIDDeviceRef device); void AddButtonsAndAxes(NSArray* elements, size_t slot); void DeviceRemove(IOHIDDeviceRef device); void ValueChanged(IOHIDValueRef value); + virtual void XboxDeviceAdd(XboxController* device) OVERRIDE; + virtual void XboxDeviceRemove(XboxController* device) OVERRIDE; + virtual void XboxValueChanged(XboxController* device, + const XboxController::Data& data) OVERRIDE; + void RegisterForNotifications(); void UnregisterFromNotifications(); + scoped_ptr<XboxDataFetcher> xbox_fetcher_; + WebKit::WebGamepads data_; // Side-band data that's not passed to the consumer, but we need to maintain // to update data_. struct AssociatedData { - IOHIDDeviceRef device_ref; - IOHIDElementRef button_elements[WebKit::WebGamepad::buttonsLengthCap]; - IOHIDElementRef axis_elements[WebKit::WebGamepad::buttonsLengthCap]; - CFIndex axis_minimums[WebKit::WebGamepad::axesLengthCap]; - CFIndex axis_maximums[WebKit::WebGamepad::axesLengthCap]; - // Function to map from device data to standard layout, if available. May - // be null if no mapping is available. - GamepadStandardMappingFunction mapper; + bool is_xbox; + union { + struct { + IOHIDDeviceRef device_ref; + IOHIDElementRef button_elements[WebKit::WebGamepad::buttonsLengthCap]; + IOHIDElementRef axis_elements[WebKit::WebGamepad::buttonsLengthCap]; + CFIndex axis_minimums[WebKit::WebGamepad::axesLengthCap]; + CFIndex axis_maximums[WebKit::WebGamepad::axesLengthCap]; + // Function to map from device data to standard layout, if available. + // May be null if no mapping is available. + GamepadStandardMappingFunction mapper; + } hid; + struct { + XboxController* device; + UInt32 location_id; + } xbox; + }; }; AssociatedData associated_[WebKit::WebGamepads::itemsLengthCap]; diff --git a/content/browser/gamepad/gamepad_platform_data_fetcher_mac.mm b/content/browser/gamepad/gamepad_platform_data_fetcher_mac.mm index b9356f2454..e97829fe2b 100644 --- a/content/browser/gamepad/gamepad_platform_data_fetcher_mac.mm +++ b/content/browser/gamepad/gamepad_platform_data_fetcher_mac.mm @@ -8,11 +8,15 @@ #include "base/memory/scoped_nsobject.h" #include "base/string16.h" #include "base/string_util.h" +#include "base/time.h" #include "base/utf_string_conversions.h" #include <IOKit/hid/IOHIDKeys.h> #import <Foundation/Foundation.h> +using WebKit::WebGamepad; +using WebKit::WebGamepads; + namespace content { namespace { @@ -44,6 +48,11 @@ const uint32_t kAxisMaximumUsageNumber = 0x35; GamepadPlatformDataFetcherMac::GamepadPlatformDataFetcherMac() : enabled_(true) { memset(associated_, 0, sizeof(associated_)); + + xbox_fetcher_.reset(new XboxDataFetcher(this)); + if (!xbox_fetcher_->RegisterForNotifications()) + xbox_fetcher_.reset(); + hid_manager_ref_.reset(IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone)); if (CFGetTypeID(hid_manager_ref_) != IOHIDManagerGetTypeID()) { @@ -87,6 +96,9 @@ void GamepadPlatformDataFetcherMac::RegisterForNotifications() { enabled_ = IOHIDManagerOpen(hid_manager_ref_, kIOHIDOptionsTypeNone) == kIOReturnSuccess; + + if (xbox_fetcher_) + xbox_fetcher_->RegisterForNotifications(); } void GamepadPlatformDataFetcherMac::UnregisterFromNotifications() { @@ -95,6 +107,8 @@ void GamepadPlatformDataFetcherMac::UnregisterFromNotifications() { CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); IOHIDManagerClose(hid_manager_ref_, kIOHIDOptionsTypeNone); + if (xbox_fetcher_) + xbox_fetcher_->UnregisterFromNotifications(); } void GamepadPlatformDataFetcherMac::PauseHint(bool pause) { @@ -109,36 +123,36 @@ GamepadPlatformDataFetcherMac::~GamepadPlatformDataFetcherMac() { } GamepadPlatformDataFetcherMac* -GamepadPlatformDataFetcherMac::InstanceFromContext( - void* context) { +GamepadPlatformDataFetcherMac::InstanceFromContext(void* context) { return reinterpret_cast<GamepadPlatformDataFetcherMac*>(context); } void GamepadPlatformDataFetcherMac::DeviceAddCallback(void* context, - IOReturn result, - void* sender, - IOHIDDeviceRef ref) { + IOReturn result, + void* sender, + IOHIDDeviceRef ref) { InstanceFromContext(context)->DeviceAdd(ref); } void GamepadPlatformDataFetcherMac::DeviceRemoveCallback(void* context, - IOReturn result, - void* sender, - IOHIDDeviceRef ref) { + IOReturn result, + void* sender, + IOHIDDeviceRef ref) { InstanceFromContext(context)->DeviceRemove(ref); } void GamepadPlatformDataFetcherMac::ValueChangedCallback(void* context, - IOReturn result, - void* sender, - IOHIDValueRef ref) { + IOReturn result, + void* sender, + IOHIDValueRef ref) { InstanceFromContext(context)->ValueChanged(ref); } void GamepadPlatformDataFetcherMac::AddButtonsAndAxes(NSArray* elements, - size_t slot) { - WebKit::WebGamepad& pad = data_.items[slot]; + size_t slot) { + WebGamepad& pad = data_.items[slot]; AssociatedData& associated = associated_[slot]; + CHECK(!associated.is_xbox); pad.axesLength = 0; pad.buttonsLength = 0; @@ -153,44 +167,75 @@ void GamepadPlatformDataFetcherMac::AddButtonsAndAxes(NSArray* elements, if (IOHIDElementGetType(element) == kIOHIDElementTypeInput_Button && usagePage == kButtonUsagePage) { uint32_t button_index = usage - 1; - if (button_index < WebKit::WebGamepad::buttonsLengthCap) { - associated.button_elements[button_index] = element; + if (button_index < WebGamepad::buttonsLengthCap) { + associated.hid.button_elements[button_index] = element; pad.buttonsLength = std::max(pad.buttonsLength, button_index + 1); } } else if (IOHIDElementGetType(element) == kIOHIDElementTypeInput_Misc) { uint32_t axis_index = usage - kAxisMinimumUsageNumber; - if (axis_index < WebKit::WebGamepad::axesLengthCap) { - associated.axis_minimums[axis_index] = + if (axis_index < WebGamepad::axesLengthCap) { + associated.hid.axis_minimums[axis_index] = IOHIDElementGetLogicalMin(element); - associated.axis_maximums[axis_index] = + associated.hid.axis_maximums[axis_index] = IOHIDElementGetLogicalMax(element); - associated.axis_elements[axis_index] = element; + associated.hid.axis_elements[axis_index] = element; pad.axesLength = std::max(pad.axesLength, axis_index + 1); } } } } +size_t GamepadPlatformDataFetcherMac::GetEmptySlot() { + // Find a free slot for this device. + for (size_t slot = 0; slot < WebGamepads::itemsLengthCap; ++slot) { + if (!data_.items[slot].connected) + return slot; + } + return WebGamepads::itemsLengthCap; +} + +size_t GamepadPlatformDataFetcherMac::GetSlotForDevice(IOHIDDeviceRef device) { + for (size_t slot = 0; slot < WebGamepads::itemsLengthCap; ++slot) { + // If we already have this device, and it's already connected, don't do + // anything now. + if (data_.items[slot].connected && + !associated_[slot].is_xbox && + associated_[slot].hid.device_ref == device) + return WebGamepads::itemsLengthCap; + } + return GetEmptySlot(); +} + +size_t GamepadPlatformDataFetcherMac::GetSlotForXboxDevice( + XboxController* device) { + for (size_t slot = 0; slot < WebGamepads::itemsLengthCap; ++slot) { + if (associated_[slot].is_xbox && + associated_[slot].xbox.location_id == device->location_id()) { + if (data_.items[slot].connected) { + // The device is already connected. No idea why we got a second "device + // added" call, but let's not add it twice. + DCHECK_EQ(associated_[slot].xbox.device, device); + return WebGamepads::itemsLengthCap; + } else { + // A device with the same location ID was previously connected, so put + // it in the same slot. + return slot; + } + } + } + return GetEmptySlot(); +} + void GamepadPlatformDataFetcherMac::DeviceAdd(IOHIDDeviceRef device) { - using WebKit::WebGamepad; - using WebKit::WebGamepads; using base::mac::CFToNSCast; using base::mac::CFCastStrict; - size_t slot; if (!enabled_) return; // Find an index for this device. - for (slot = 0; slot < WebGamepads::itemsLengthCap; ++slot) { - // If we already have this device, and it's already connected, don't do - // anything now. - if (associated_[slot].device_ref == device && data_.items[slot].connected) - return; - if (!data_.items[slot].connected) - break; - } + size_t slot = GetSlotForDevice(device); // We can't handle this many connected devices. if (slot == WebGamepads::itemsLengthCap) @@ -208,13 +253,13 @@ void GamepadPlatformDataFetcherMac::DeviceAdd(IOHIDDeviceRef device) { char vendor_as_str[5], product_as_str[5]; snprintf(vendor_as_str, sizeof(vendor_as_str), "%04x", vendor_int); snprintf(product_as_str, sizeof(product_as_str), "%04x", product_int); - associated_[slot].mapper = + associated_[slot].hid.mapper = GetGamepadStandardMappingFunction(vendor_as_str, product_as_str); NSString* ident = [NSString stringWithFormat: @"%@ (%sVendor: %04x Product: %04x)", product, - associated_[slot].mapper ? "STANDARD GAMEPAD " : "", + associated_[slot].hid.mapper ? "STANDARD GAMEPAD " : "", vendor_int, product_int]; NSData* as16 = [ident dataUsingEncoding:NSUTF16LittleEndianStringEncoding]; @@ -228,21 +273,22 @@ void GamepadPlatformDataFetcherMac::DeviceAdd(IOHIDDeviceRef device) { IOHIDDeviceCopyMatchingElements(device, NULL, kIOHIDOptionsTypeNone)); AddButtonsAndAxes(CFToNSCast(elements), slot); - associated_[slot].device_ref = device; + associated_[slot].hid.device_ref = device; data_.items[slot].connected = true; if (slot >= data_.length) data_.length = slot + 1; } void GamepadPlatformDataFetcherMac::DeviceRemove(IOHIDDeviceRef device) { - using WebKit::WebGamepads; - size_t slot; if (!enabled_) return; // Find the index for this device. + size_t slot; for (slot = 0; slot < WebGamepads::itemsLengthCap; ++slot) { - if (associated_[slot].device_ref == device && data_.items[slot].connected) + if (data_.items[slot].connected && + !associated_[slot].is_xbox && + associated_[slot].hid.device_ref == device) break; } DCHECK(slot < WebGamepads::itemsLengthCap); @@ -261,18 +307,20 @@ void GamepadPlatformDataFetcherMac::ValueChanged(IOHIDValueRef value) { // Find device slot. size_t slot; for (slot = 0; slot < data_.length; ++slot) { - if (data_.items[slot].connected && associated_[slot].device_ref == device) + if (data_.items[slot].connected && + !associated_[slot].is_xbox && + associated_[slot].hid.device_ref == device) break; } if (slot == data_.length) return; - WebKit::WebGamepad& pad = data_.items[slot]; + WebGamepad& pad = data_.items[slot]; AssociatedData& associated = associated_[slot]; // Find and fill in the associated button event, if any. for (size_t i = 0; i < pad.buttonsLength; ++i) { - if (associated.button_elements[i] == element) { + if (associated.hid.button_elements[i] == element) { pad.buttons[i] = IOHIDValueGetIntegerValue(value) ? 1.f : 0.f; pad.timestamp = std::max(pad.timestamp, IOHIDValueGetTimeStamp(value)); return; @@ -281,30 +329,110 @@ void GamepadPlatformDataFetcherMac::ValueChanged(IOHIDValueRef value) { // Find and fill in the associated axis event, if any. for (size_t i = 0; i < pad.axesLength; ++i) { - if (associated.axis_elements[i] == element) { + if (associated.hid.axis_elements[i] == element) { pad.axes[i] = NormalizeAxis(IOHIDValueGetIntegerValue(value), - associated.axis_minimums[i], - associated.axis_maximums[i]); + associated.hid.axis_minimums[i], + associated.hid.axis_maximums[i]); pad.timestamp = std::max(pad.timestamp, IOHIDValueGetTimeStamp(value)); return; } } } -void GamepadPlatformDataFetcherMac::GetGamepadData( - WebKit::WebGamepads* pads, - bool) { - if (!enabled_) { +void GamepadPlatformDataFetcherMac::XboxDeviceAdd(XboxController* device) { + if (!enabled_) + return; + + size_t slot = GetSlotForXboxDevice(device); + + // We can't handle this many connected devices. + if (slot == WebGamepads::itemsLengthCap) + return; + + device->SetLEDPattern( + (XboxController::LEDPattern)(XboxController::LED_FLASH_TOP_LEFT + slot)); + + NSString* ident = + [NSString stringWithFormat: + @"Xbox 360 Controller (STANDARD GAMEPAD Vendor: %04x Product: %04x)", + device->GetProductId(), device->GetVendorId()]; + NSData* as16 = [ident dataUsingEncoding:NSUTF16StringEncoding]; + const size_t kOutputLengthBytes = sizeof(data_.items[slot].id); + memset(&data_.items[slot].id, 0, kOutputLengthBytes); + [as16 getBytes:data_.items[slot].id + length:kOutputLengthBytes - sizeof(WebKit::WebUChar)]; + + associated_[slot].is_xbox = true; + associated_[slot].xbox.device = device; + associated_[slot].xbox.location_id = device->location_id(); + data_.items[slot].connected = true; + data_.items[slot].axesLength = 4; + data_.items[slot].buttonsLength = 17; + data_.items[slot].timestamp = 0; + if (slot >= data_.length) + data_.length = slot + 1; +} + +void GamepadPlatformDataFetcherMac::XboxDeviceRemove(XboxController* device) { + if (!enabled_) + return; + + // Find the index for this device. + size_t slot; + for (slot = 0; slot < WebGamepads::itemsLengthCap; ++slot) { + if (data_.items[slot].connected && + associated_[slot].is_xbox && + associated_[slot].xbox.device == device) + break; + } + DCHECK(slot < WebGamepads::itemsLengthCap); + // Leave associated location id so that the controller will be reconnected in + // the same slot if it is plugged in again. Simply mark it as disconnected. + data_.items[slot].connected = false; +} + +void GamepadPlatformDataFetcherMac::XboxValueChanged( + XboxController* device, const XboxController::Data& data) { + // Find device slot. + size_t slot; + for (slot = 0; slot < data_.length; ++slot) { + if (data_.items[slot].connected && + associated_[slot].is_xbox && + associated_[slot].xbox.device == device) + break; + } + if (slot == data_.length) + return; + + WebGamepad& pad = data_.items[slot]; + + for (size_t i = 0; i < 6; i++) { + pad.buttons[i] = data.buttons[i] ? 1.0f : 0.0f; + } + pad.buttons[6] = data.triggers[0]; + pad.buttons[7] = data.triggers[1]; + for (size_t i = 8; i < 17; i++) { + pad.buttons[i] = data.buttons[i - 2] ? 1.0f : 0.0f; + } + for (size_t i = 0; i < arraysize(data.axes); i++) { + pad.axes[i] = data.axes[i]; + } + + pad.timestamp = base::TimeTicks::Now().ToInternalValue(); +} + +void GamepadPlatformDataFetcherMac::GetGamepadData(WebGamepads* pads, bool) { + if (!enabled_ && !xbox_fetcher_) { pads->length = 0; return; } // Copy to the current state to the output buffer, using the mapping // function, if there is one available. - pads->length = WebKit::WebGamepads::itemsLengthCap; - for (size_t i = 0; i < WebKit::WebGamepads::itemsLengthCap; ++i) { - if (associated_[i].mapper) - associated_[i].mapper(data_.items[i], &pads->items[i]); + pads->length = WebGamepads::itemsLengthCap; + for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i) { + if (!associated_[i].is_xbox && associated_[i].hid.mapper) + associated_[i].hid.mapper(data_.items[i], &pads->items[i]); else pads->items[i] = data_.items[i]; } diff --git a/content/browser/gamepad/gamepad_platform_data_fetcher_win.cc b/content/browser/gamepad/gamepad_platform_data_fetcher_win.cc index 37af979718..90a1b0df0a 100644 --- a/content/browser/gamepad/gamepad_platform_data_fetcher_win.cc +++ b/content/browser/gamepad/gamepad_platform_data_fetcher_win.cc @@ -473,15 +473,15 @@ void GamepadPlatformDataFetcherWin::GetDirectInputPadData( bool GamepadPlatformDataFetcherWin::GetXInputDllFunctions() { xinput_get_capabilities_ = NULL; xinput_get_state_ = NULL; - xinput_enable_ = static_cast<XInputEnableFunc>( + xinput_enable_ = reinterpret_cast<XInputEnableFunc>( xinput_dll_.GetFunctionPointer("XInputEnable")); if (!xinput_enable_) return false; - xinput_get_capabilities_ = static_cast<XInputGetCapabilitiesFunc>( + xinput_get_capabilities_ = reinterpret_cast<XInputGetCapabilitiesFunc>( xinput_dll_.GetFunctionPointer("XInputGetCapabilities")); if (!xinput_get_capabilities_) return false; - xinput_get_state_ = static_cast<XInputGetStateFunc>( + xinput_get_state_ = reinterpret_cast<XInputGetStateFunc>( xinput_dll_.GetFunctionPointer("XInputGetState")); if (!xinput_get_state_) return false; diff --git a/content/browser/gamepad/gamepad_provider.cc b/content/browser/gamepad/gamepad_provider.cc index 1dad4829f8..b4fe67fc81 100644 --- a/content/browser/gamepad/gamepad_provider.cc +++ b/content/browser/gamepad/gamepad_provider.cc @@ -113,8 +113,17 @@ void GamepadProvider::Initialize(scoped_ptr<GamepadDataFetcher> fetcher) { memset(hwbuf, 0, sizeof(GamepadHardwareBuffer)); polling_thread_.reset(new base::Thread("Gamepad polling thread")); - polling_thread_->StartWithOptions( - base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); +#if defined(OS_MACOSX) + // On Mac, the data fetcher uses IOKit which depends on CFRunLoop, so the + // message loop needs to be a UI-type loop. + const base::MessageLoop::Type kMessageLoopType = base::MessageLoop::TYPE_UI; +#else + // On Linux, the data fetcher needs to watch file descriptors, so the message + // loop needs to be a libevent loop. On Windows it doesn't matter what the + // loop is. + const base::MessageLoop::Type kMessageLoopType = base::MessageLoop::TYPE_IO; +#endif + polling_thread_->StartWithOptions(base::Thread::Options(kMessageLoopType, 0)); polling_thread_->message_loop()->PostTask( FROM_HERE, diff --git a/content/browser/gamepad/xbox_data_fetcher_mac.cc b/content/browser/gamepad/xbox_data_fetcher_mac.cc new file mode 100644 index 0000000000..a3239f7605 --- /dev/null +++ b/content/browser/gamepad/xbox_data_fetcher_mac.cc @@ -0,0 +1,627 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/gamepad/xbox_data_fetcher_mac.h" + +#include <algorithm> +#include <cmath> +#include <limits> + +#include <CoreFoundation/CoreFoundation.h> +#include <IOKit/IOCFPlugIn.h> +#include <IOKit/IOKitLib.h> +#include <IOKit/usb/IOUSBLib.h> +#include <IOKit/usb/USB.h> + +#include "base/logging.h" +#include "base/mac/foundation_util.h" + +namespace { +const int kVendorMicrosoft = 0x045e; +const int kProduct360Controller = 0x028e; + +const int kReadEndpoint = 1; +const int kControlEndpoint = 2; + +enum { + STATUS_MESSAGE_BUTTONS = 0, + STATUS_MESSAGE_LED = 1, + + // Apparently this message tells you if the rumble pack is disabled in the + // controller. If the rumble pack is disabled, vibration control messages + // have no effect. + STATUS_MESSAGE_RUMBLE = 3, +}; + +enum { + CONTROL_MESSAGE_SET_RUMBLE = 0, + CONTROL_MESSAGE_SET_LED = 1, +}; + +#pragma pack(push, 1) +struct ButtonData { + bool dpad_up : 1; + bool dpad_down : 1; + bool dpad_left : 1; + bool dpad_right : 1; + + bool start : 1; + bool back : 1; + bool stick_left_click : 1; + bool stick_right_click : 1; + + bool bumper_left : 1; + bool bumper_right : 1; + bool guide : 1; + bool dummy1 : 1; // Always 0. + + bool a : 1; + bool b : 1; + bool x : 1; + bool y : 1; + + uint8 trigger_left; + uint8 trigger_right; + + int16 stick_left_x; + int16 stick_left_y; + int16 stick_right_x; + int16 stick_right_y; + + // Always 0. + uint32 dummy2; + uint16 dummy3; +}; +#pragma pack(pop) + +COMPILE_ASSERT(sizeof(ButtonData) == 0x12, xbox_button_data_wrong_size); + +// From MSDN: +// http://msdn.microsoft.com/en-us/library/windows/desktop/ee417001(v=vs.85).aspx#dead_zone +const int16 kLeftThumbDeadzone = 7849; +const int16 kRightThumbDeadzone = 8689; +const uint8 kTriggerDeadzone = 30; + +void NormalizeAxis(int16 x, + int16 y, + int16 deadzone, + float* x_out, + float* y_out) { + float x_val = x; + float y_val = y; + + // Determine how far the stick is pushed. + float real_magnitude = std::sqrt(x_val * x_val + y_val * y_val); + + // Check if the controller is outside a circular dead zone. + if (real_magnitude > deadzone) { + // Clip the magnitude at its expected maximum value. + float magnitude = std::min(32767.0f, real_magnitude); + + // Adjust magnitude relative to the end of the dead zone. + magnitude -= deadzone; + + // Normalize the magnitude with respect to its expected range giving a + // magnitude value of 0.0 to 1.0 + float ratio = (magnitude / (32767 - deadzone)) / real_magnitude; + + // Y is negated because xbox controllers have an opposite sign from + // the 'standard controller' recommendations. + *x_out = x_val * ratio; + *y_out = -y_val * ratio; + } else { + // If the controller is in the deadzone zero out the magnitude. + *x_out = *y_out = 0.0f; + } +} + +float NormalizeTrigger(uint8 value) { + return value < kTriggerDeadzone ? 0 : + static_cast<float>(value - kTriggerDeadzone) / + (std::numeric_limits<uint8>::max() - kTriggerDeadzone); +} + +void NormalizeButtonData(const ButtonData& data, + XboxController::Data* normalized_data) { + normalized_data->buttons[0] = data.a; + normalized_data->buttons[1] = data.b; + normalized_data->buttons[2] = data.x; + normalized_data->buttons[3] = data.y; + normalized_data->buttons[4] = data.bumper_left; + normalized_data->buttons[5] = data.bumper_right; + normalized_data->buttons[6] = data.back; + normalized_data->buttons[7] = data.start; + normalized_data->buttons[8] = data.stick_left_click; + normalized_data->buttons[9] = data.stick_right_click; + normalized_data->buttons[10] = data.dpad_up; + normalized_data->buttons[11] = data.dpad_down; + normalized_data->buttons[12] = data.dpad_left; + normalized_data->buttons[13] = data.dpad_right; + normalized_data->buttons[14] = data.guide; + normalized_data->triggers[0] = NormalizeTrigger(data.trigger_left); + normalized_data->triggers[1] = NormalizeTrigger(data.trigger_right); + NormalizeAxis(data.stick_left_x, + data.stick_left_y, + kLeftThumbDeadzone, + &normalized_data->axes[0], + &normalized_data->axes[1]); + NormalizeAxis(data.stick_right_x, + data.stick_right_y, + kRightThumbDeadzone, + &normalized_data->axes[2], + &normalized_data->axes[3]); +} + +} // namespace + +XboxController::XboxController(Delegate* delegate) + : device_(NULL), + interface_(NULL), + device_is_open_(false), + interface_is_open_(false), + read_buffer_size_(0), + led_pattern_(LED_NUM_PATTERNS), + location_id_(0), + delegate_(delegate) { +} + +XboxController::~XboxController() { + if (source_) + CFRunLoopSourceInvalidate(source_); + if (interface_ && interface_is_open_) + (*interface_)->USBInterfaceClose(interface_); + if (device_ && device_is_open_) + (*device_)->USBDeviceClose(device_); +} + +bool XboxController::OpenDevice(io_service_t service) { + IOCFPlugInInterface **plugin; + SInt32 score; // Unused, but required for IOCreatePlugInInterfaceForService. + kern_return_t kr = + IOCreatePlugInInterfaceForService(service, + kIOUSBDeviceUserClientTypeID, + kIOCFPlugInInterfaceID, + &plugin, + &score); + if (kr != KERN_SUCCESS) + return false; + base::mac::ScopedIOPluginInterface<IOCFPlugInInterface> plugin_ref(plugin); + + HRESULT res = + (*plugin)->QueryInterface(plugin, + CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID320), + (LPVOID *)&device_); + if (!SUCCEEDED(res) || !device_) + return false; + + UInt16 vendor_id; + kr = (*device_)->GetDeviceVendor(device_, &vendor_id); + if (kr != KERN_SUCCESS) + return false; + UInt16 product_id; + kr = (*device_)->GetDeviceProduct(device_, &product_id); + if (kr != KERN_SUCCESS) + return false; + if (vendor_id != kVendorMicrosoft || product_id != kProduct360Controller) + return false; + + // Open the device and configure it. + kr = (*device_)->USBDeviceOpen(device_); + if (kr != KERN_SUCCESS) + return false; + device_is_open_ = true; + + // Xbox controllers have one configuration option which has configuration + // value 1. Try to set it and fail if it couldn't be configured. + IOUSBConfigurationDescriptorPtr config_desc; + kr = (*device_)->GetConfigurationDescriptorPtr(device_, 0, &config_desc); + if (kr != KERN_SUCCESS) + return false; + kr = (*device_)->SetConfiguration(device_, config_desc->bConfigurationValue); + if (kr != KERN_SUCCESS) + return false; + + // The device has 4 interfaces. They are as follows: + // Protocol 1: + // - Endpoint 1 (in) : Controller events, including button presses. + // - Endpoint 2 (out): Rumble pack and LED control + // Protocol 2 has a single endpoint to read from a connected ChatPad device. + // Protocol 3 is used by a connected headset device. + // The device also has an interface on subclass 253, protocol 10 with no + // endpoints. It is unused. + // + // We don't currently support the ChatPad or headset, so protocol 1 is the + // only protocol we care about. + // + // For more detail, see + // https://github.com/Grumbel/xboxdrv/blob/master/PROTOCOL + IOUSBFindInterfaceRequest request; + request.bInterfaceClass = 255; + request.bInterfaceSubClass = 93; + request.bInterfaceProtocol = 1; + request.bAlternateSetting = kIOUSBFindInterfaceDontCare; + io_iterator_t iter; + kr = (*device_)->CreateInterfaceIterator(device_, &request, &iter); + if (kr != KERN_SUCCESS) + return false; + base::mac::ScopedIOObject<io_iterator_t> iter_ref(iter); + + // There should be exactly one USB interface which matches the requested + // settings. + io_service_t usb_interface = IOIteratorNext(iter); + if (!usb_interface) + return false; + + // We need to make an InterfaceInterface to communicate with the device + // endpoint. This is the same process as earlier: first make a + // PluginInterface from the io_service then make the InterfaceInterface from + // that. + IOCFPlugInInterface **plugin_interface; + kr = IOCreatePlugInInterfaceForService(usb_interface, + kIOUSBInterfaceUserClientTypeID, + kIOCFPlugInInterfaceID, + &plugin_interface, + &score); + if (kr != KERN_SUCCESS || !plugin_interface) + return false; + base::mac::ScopedIOPluginInterface<IOCFPlugInInterface> interface_ref( + plugin_interface); + + // Release the USB interface, and any subsequent interfaces returned by the + // iterator. (There shouldn't be any, but in case a future device does + // contain more interfaces, this will serve to avoid memory leaks.) + do { + IOObjectRelease(usb_interface); + } while ((usb_interface = IOIteratorNext(iter))); + + // Actually create the interface. + res = (*plugin_interface)->QueryInterface( + plugin_interface, + CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID300), + (LPVOID *)&interface_); + + if (!SUCCEEDED(res) || !interface_) + return false; + + // Actually open the interface. + kr = (*interface_)->USBInterfaceOpen(interface_); + if (kr != KERN_SUCCESS) + return false; + interface_is_open_ = true; + + CFRunLoopSourceRef source_ref; + kr = (*interface_)->CreateInterfaceAsyncEventSource(interface_, &source_ref); + if (kr != KERN_SUCCESS || !source_ref) + return false; + source_.reset(source_ref); + CFRunLoopAddSource(CFRunLoopGetCurrent(), source_, kCFRunLoopDefaultMode); + + // The interface should have two pipes. Pipe 1 with direction kUSBIn and pipe + // 2 with direction kUSBOut. Both pipes should have type kUSBInterrupt. + uint8 num_endpoints; + kr = (*interface_)->GetNumEndpoints(interface_, &num_endpoints); + if (kr != KERN_SUCCESS || num_endpoints < 2) + return false; + + for (int i = 1; i <= 2; i++) { + uint8 direction; + uint8 number; + uint8 transfer_type; + uint16 max_packet_size; + uint8 interval; + + kr = (*interface_)->GetPipeProperties(interface_, + i, + &direction, + &number, + &transfer_type, + &max_packet_size, + &interval); + if (kr != KERN_SUCCESS || transfer_type != kUSBInterrupt) + return false; + if (i == kReadEndpoint) { + if (direction != kUSBIn) + return false; + if (max_packet_size > 32) + return false; + read_buffer_.reset(new uint8[max_packet_size]); + read_buffer_size_ = max_packet_size; + QueueRead(); + } else if (i == kControlEndpoint) { + if (direction != kUSBOut) + return false; + } + } + + // The location ID is unique per controller, and can be used to track + // controllers through reconnections (though if a controller is detached from + // one USB hub and attached to another, the location ID will change). + kr = (*device_)->GetLocationID(device_, &location_id_); + if (kr != KERN_SUCCESS) + return false; + + return true; +} + +void XboxController::SetLEDPattern(LEDPattern pattern) { + led_pattern_ = pattern; + const UInt8 length = 3; + + // This buffer will be released in WriteComplete when WritePipeAsync + // finishes. + UInt8* buffer = new UInt8[length]; + buffer[0] = static_cast<UInt8>(CONTROL_MESSAGE_SET_LED); + buffer[1] = length; + buffer[2] = static_cast<UInt8>(pattern); + kern_return_t kr = (*interface_)->WritePipeAsync(interface_, + kControlEndpoint, + buffer, + (UInt32)length, + WriteComplete, + buffer); + if (kr != KERN_SUCCESS) { + delete[] buffer; + IOError(); + return; + } +} + +int XboxController::GetVendorId() const { + return kVendorMicrosoft; +} + +int XboxController::GetProductId() const { + return kProduct360Controller; +} + +void XboxController::WriteComplete(void* context, IOReturn result, void* arg0) { + UInt8* buffer = static_cast<UInt8*>(context); + delete[] buffer; + + // Ignoring any errors sending data, because they will usually only occur + // when the device is disconnected, in which case it really doesn't matter if + // the data got to the controller or not. + if (result != kIOReturnSuccess) + return; +} + +void XboxController::GotData(void* context, IOReturn result, void* arg0) { + size_t bytes_read = reinterpret_cast<size_t>(arg0); + XboxController* controller = static_cast<XboxController*>(context); + + if (result != kIOReturnSuccess) { + // This will happen if the device was disconnected. The gamepad has + // probably been destroyed by a meteorite. + controller->IOError(); + return; + } + + controller->ProcessPacket(bytes_read); + + // Queue up another read. + controller->QueueRead(); +} + +void XboxController::ProcessPacket(size_t length) { + if (length < 2) return; + DCHECK(length <= read_buffer_size_); + if (length > read_buffer_size_) { + IOError(); + return; + } + uint8* buffer = read_buffer_.get(); + + if (buffer[1] != length) + // Length in packet doesn't match length reported by USB. + return; + + uint8 type = buffer[0]; + buffer += 2; + length -= 2; + switch (type) { + case STATUS_MESSAGE_BUTTONS: { + if (length != sizeof(ButtonData)) + return; + ButtonData* data = reinterpret_cast<ButtonData*>(buffer); + Data normalized_data; + NormalizeButtonData(*data, &normalized_data); + delegate_->XboxControllerGotData(this, normalized_data); + break; + } + case STATUS_MESSAGE_LED: + if (length != 3) + return; + // The controller sends one of these messages every time the LED pattern + // is set, as well as once when it is plugged in. + if (led_pattern_ == LED_NUM_PATTERNS && buffer[0] < LED_NUM_PATTERNS) + led_pattern_ = static_cast<LEDPattern>(buffer[0]); + break; + default: + // Unknown packet: ignore! + break; + } +} + +void XboxController::QueueRead() { + kern_return_t kr = (*interface_)->ReadPipeAsync(interface_, + kReadEndpoint, + read_buffer_.get(), + read_buffer_size_, + GotData, + this); + if (kr != KERN_SUCCESS) + IOError(); +} + +void XboxController::IOError() { + delegate_->XboxControllerError(this); +} + +//----------------------------------------------------------------------------- + +XboxDataFetcher::XboxDataFetcher(Delegate* delegate) + : delegate_(delegate), + listening_(false), + source_(NULL), + port_(NULL) { +} + +XboxDataFetcher::~XboxDataFetcher() { + while (!controllers_.empty()) { + RemoveController(*controllers_.begin()); + } + UnregisterFromNotifications(); +} + +void XboxDataFetcher::DeviceAdded(void* context, io_iterator_t iterator) { + DCHECK(context); + XboxDataFetcher* fetcher = static_cast<XboxDataFetcher*>(context); + io_service_t ref; + while ((ref = IOIteratorNext(iterator))) { + base::mac::ScopedIOObject<io_service_t> scoped_ref(ref); + XboxController* controller = new XboxController(fetcher); + if (controller->OpenDevice(ref)) { + fetcher->AddController(controller); + } else { + delete controller; + } + } +} + +void XboxDataFetcher::DeviceRemoved(void* context, io_iterator_t iterator) { + DCHECK(context); + XboxDataFetcher* fetcher = static_cast<XboxDataFetcher*>(context); + io_service_t ref; + while ((ref = IOIteratorNext(iterator))) { + base::mac::ScopedIOObject<io_service_t> scoped_ref(ref); + base::mac::ScopedCFTypeRef<CFNumberRef> number( + base::mac::CFCastStrict<CFNumberRef>(IORegistryEntryCreateCFProperty( + ref, + CFSTR(kUSBDevicePropertyLocationID), + kCFAllocatorDefault, + kNilOptions))); + UInt32 location_id = 0; + CFNumberGetValue(number, kCFNumberSInt32Type, &location_id); + fetcher->RemoveControllerByLocationID(location_id); + } +} + +bool XboxDataFetcher::RegisterForNotifications() { + if (listening_) + return true; + base::mac::ScopedCFTypeRef<CFNumberRef> vendor_cf( + CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, + &kVendorMicrosoft)); + base::mac::ScopedCFTypeRef<CFNumberRef> product_cf( + CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, + &kProduct360Controller)); + base::mac::ScopedCFTypeRef<CFMutableDictionaryRef> matching_dict( + IOServiceMatching(kIOUSBDeviceClassName)); + if (!matching_dict) + return false; + CFDictionarySetValue(matching_dict, CFSTR(kUSBVendorID), vendor_cf); + CFDictionarySetValue(matching_dict, CFSTR(kUSBProductID), product_cf); + port_ = IONotificationPortCreate(kIOMasterPortDefault); + if (!port_) + return false; + source_ = IONotificationPortGetRunLoopSource(port_); + if (!source_) + return false; + CFRunLoopAddSource(CFRunLoopGetCurrent(), source_, kCFRunLoopDefaultMode); + + listening_ = true; + + // IOServiceAddMatchingNotification() releases the dictionary when it's done. + // Retain it before each call to IOServiceAddMatchingNotification to keep + // things balanced. + CFRetain(matching_dict); + io_iterator_t device_added_iter; + IOReturn ret; + ret = IOServiceAddMatchingNotification(port_, + kIOFirstMatchNotification, + matching_dict, + DeviceAdded, + this, + &device_added_iter); + device_added_iter_.reset(device_added_iter); + if (ret != kIOReturnSuccess) { + LOG(ERROR) << "Error listening for Xbox controller add events: " << ret; + return false; + } + DeviceAdded(this, device_added_iter_.get()); + + CFRetain(matching_dict); + io_iterator_t device_removed_iter; + ret = IOServiceAddMatchingNotification(port_, + kIOTerminatedNotification, + matching_dict, + DeviceRemoved, + this, + &device_removed_iter); + device_removed_iter_.reset(device_removed_iter); + if (ret != kIOReturnSuccess) { + LOG(ERROR) << "Error listening for Xbox controller remove events: " << ret; + return false; + } + DeviceRemoved(this, device_removed_iter_.get()); + return true; +} + +void XboxDataFetcher::UnregisterFromNotifications() { + if (!listening_) + return; + listening_ = false; + if (source_) + CFRunLoopSourceInvalidate(source_); + if (port_) + IONotificationPortDestroy(port_); + port_ = NULL; +} + +XboxController* XboxDataFetcher::ControllerForLocation(UInt32 location_id) { + for (std::set<XboxController*>::iterator i = controllers_.begin(); + i != controllers_.end(); + ++i) { + if ((*i)->location_id() == location_id) + return *i; + } + return NULL; +} + +void XboxDataFetcher::AddController(XboxController* controller) { + DCHECK(!ControllerForLocation(controller->location_id())) + << "Controller with location ID " << controller->location_id() + << " already exists in the set of controllers."; + controllers_.insert(controller); + delegate_->XboxDeviceAdd(controller); +} + +void XboxDataFetcher::RemoveController(XboxController* controller) { + delegate_->XboxDeviceRemove(controller); + controllers_.erase(controller); + delete controller; +} + +void XboxDataFetcher::RemoveControllerByLocationID(uint32 location_id) { + XboxController* controller = NULL; + for (std::set<XboxController*>::iterator i = controllers_.begin(); + i != controllers_.end(); + ++i) { + if ((*i)->location_id() == location_id) { + controller = *i; + break; + } + } + if (controller) + RemoveController(controller); +} + +void XboxDataFetcher::XboxControllerGotData(XboxController* controller, + const XboxController::Data& data) { + delegate_->XboxValueChanged(controller, data); +} + +void XboxDataFetcher::XboxControllerError(XboxController* controller) { + RemoveController(controller); +} diff --git a/content/browser/gamepad/xbox_data_fetcher_mac.h b/content/browser/gamepad/xbox_data_fetcher_mac.h new file mode 100644 index 0000000000..74eda1b523 --- /dev/null +++ b/content/browser/gamepad/xbox_data_fetcher_mac.h @@ -0,0 +1,167 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_GAMEPAD_XBOX_DATA_FETCHER_MAC_H_ +#define CONTENT_BROWSER_GAMEPAD_XBOX_DATA_FETCHER_MAC_H_ + +#include <CoreFoundation/CoreFoundation.h> +#include <IOKit/IOKitLib.h> + +#include <set> + +#include "base/basictypes.h" +#include "base/mac/scoped_cftyperef.h" +#include "base/mac/scoped_ioobject.h" +#include "base/mac/scoped_ioplugininterface.h" +#include "base/memory/scoped_ptr.h" + +class XboxController { + public: + enum LEDPattern { + LED_OFF = 0, + + // 2 quick flashes, then a series of slow flashes (about 1 per second). + LED_FLASH = 1, + + // Flash three times then hold the LED on. This is the standard way to tell + // the player which player number they are. + LED_FLASH_TOP_LEFT = 2, + LED_FLASH_TOP_RIGHT = 3, + LED_FLASH_BOTTOM_LEFT = 4, + LED_FLASH_BOTTOM_RIGHT = 5, + + // Simply turn on the specified LED and turn all other LEDs off. + LED_HOLD_TOP_LEFT = 6, + LED_HOLD_TOP_RIGHT = 7, + LED_HOLD_BOTTOM_LEFT = 8, + LED_HOLD_BOTTOM_RIGHT = 9, + + LED_ROTATE = 10, + + LED_FLASH_FAST = 11, + LED_FLASH_SLOW = 12, // Flash about once per 3 seconds + + // Flash alternating LEDs for a few seconds, then flash all LEDs about once + // per second + LED_ALTERNATE_PATTERN = 13, + + // 14 is just another boring flashing speed. + + // Flash all LEDs once then go black. + LED_FLASH_ONCE = 15, + + LED_NUM_PATTERNS + }; + + struct Data { + bool buttons[15]; + float triggers[2]; + float axes[4]; + }; + + class Delegate { + public: + virtual void XboxControllerGotData(XboxController* controller, + const Data& data) = 0; + virtual void XboxControllerError(XboxController* controller) = 0; + }; + + explicit XboxController(Delegate* delegate_); + virtual ~XboxController(); + + bool OpenDevice(io_service_t service); + + void SetLEDPattern(LEDPattern pattern); + + UInt32 location_id() { return location_id_; } + int GetVendorId() const; + int GetProductId() const; + + private: + static void WriteComplete(void* context, IOReturn result, void* arg0); + static void GotData(void* context, IOReturn result, void* arg0); + + void ProcessPacket(size_t length); + void QueueRead(); + + void IOError(); + + // Handle for the USB device. IOUSBDeviceStruct320 is the latest version of + // the device API that is supported on Mac OS 10.6. + base::mac::ScopedIOPluginInterface<struct IOUSBDeviceStruct320> device_; + + // Handle for the interface on the device which sends button and analog data. + // The other interfaces (for the ChatPad and headset) are ignored. + base::mac::ScopedIOPluginInterface<struct IOUSBInterfaceStruct300> interface_; + + bool device_is_open_; + bool interface_is_open_; + + base::mac::ScopedCFTypeRef<CFRunLoopSourceRef> source_; + + // This will be set to the max packet size reported by the interface, which + // is 32 bytes. I would have expected USB to do message framing itself, but + // somehow we still sometimes (rarely!) get packets off the interface which + // aren't correctly framed. The 360 controller frames its packets with a 2 + // byte header (type, total length) so we can reframe the packet data + // ourselves. + uint16 read_buffer_size_; + scoped_ptr<uint8[]> read_buffer_; + + // The pattern that the LEDs on the device are currently displaying, or + // LED_NUM_PATTERNS if unknown. + LEDPattern led_pattern_; + + UInt32 location_id_; + + Delegate* delegate_; + + DISALLOW_COPY_AND_ASSIGN(XboxController); +}; + +class XboxDataFetcher : public XboxController::Delegate { + public: + class Delegate { + public: + virtual void XboxDeviceAdd(XboxController* device) = 0; + virtual void XboxDeviceRemove(XboxController* device) = 0; + virtual void XboxValueChanged(XboxController* device, + const XboxController::Data& data) = 0; + }; + + explicit XboxDataFetcher(Delegate* delegate); + virtual ~XboxDataFetcher(); + + bool RegisterForNotifications(); + void UnregisterFromNotifications(); + + XboxController* ControllerForLocation(UInt32 location_id); + + private: + static void DeviceAdded(void* context, io_iterator_t iterator); + static void DeviceRemoved(void* context, io_iterator_t iterator); + void AddController(XboxController* controller); + void RemoveController(XboxController* controller); + void RemoveControllerByLocationID(uint32 id); + virtual void XboxControllerGotData(XboxController* controller, + const XboxController::Data& data) OVERRIDE; + virtual void XboxControllerError(XboxController* controller) OVERRIDE; + + Delegate* delegate_; + + std::set<XboxController*> controllers_; + + bool listening_; + + // port_ owns source_, so this doesn't need to be a ScopedCFTypeRef, but we + // do need to maintain a reference to it so we can invalidate it. + CFRunLoopSourceRef source_; + IONotificationPortRef port_; + base::mac::ScopedIOObject<io_iterator_t> device_added_iter_; + base::mac::ScopedIOObject<io_iterator_t> device_removed_iter_; + + DISALLOW_COPY_AND_ASSIGN(XboxDataFetcher); +}; + +#endif // CONTENT_BROWSER_GAMEPAD_XBOX_DATA_FETCHER_MAC_H_ diff --git a/content/browser/geolocation/location_arbitrator_impl.cc b/content/browser/geolocation/location_arbitrator_impl.cc index 7720c55723..4fa19b5a8d 100644 --- a/content/browser/geolocation/location_arbitrator_impl.cc +++ b/content/browser/geolocation/location_arbitrator_impl.cc @@ -29,7 +29,8 @@ GeolocationArbitratorImpl::GeolocationArbitratorImpl( const LocationUpdateCallback& callback) : callback_(callback), position_provider_(NULL), - is_permission_granted_(false) { + is_permission_granted_(false), + is_running_(false) { } GeolocationArbitratorImpl::~GeolocationArbitratorImpl() { @@ -49,6 +50,7 @@ void GeolocationArbitratorImpl::OnPermissionGranted() { void GeolocationArbitratorImpl::StartProviders(bool use_high_accuracy) { // Stash options as OnAccessTokenStoresLoaded has not yet been called. + is_running_ = true; use_high_accuracy_ = use_high_accuracy; if (providers_.empty()) { DCHECK(DefaultNetworkProviderURL().is_valid()); @@ -69,12 +71,13 @@ void GeolocationArbitratorImpl::DoStartProviders() { void GeolocationArbitratorImpl::StopProviders() { providers_.clear(); + is_running_ = false; } void GeolocationArbitratorImpl::OnAccessTokenStoresLoaded( AccessTokenStore::AccessTokenSet access_token_set, net::URLRequestContextGetter* context_getter) { - if (!providers_.empty()) { + if (!is_running_ || !providers_.empty()) { // A second StartProviders() call may have arrived before the first // completed. return; diff --git a/content/browser/geolocation/location_arbitrator_impl.h b/content/browser/geolocation/location_arbitrator_impl.h index 38265afea6..f4eb4e9115 100644 --- a/content/browser/geolocation/location_arbitrator_impl.h +++ b/content/browser/geolocation/location_arbitrator_impl.h @@ -92,6 +92,9 @@ class CONTENT_EXPORT GeolocationArbitratorImpl // The current best estimate of our position. Geoposition position_; + // Tracks whether providers should be running. + bool is_running_; + DISALLOW_COPY_AND_ASSIGN(GeolocationArbitratorImpl); }; diff --git a/content/browser/geolocation/wifi_data_provider_chromeos.cc b/content/browser/geolocation/wifi_data_provider_chromeos.cc index cf0b58a9a8..44fd22822c 100644 --- a/content/browser/geolocation/wifi_data_provider_chromeos.cc +++ b/content/browser/geolocation/wifi_data_provider_chromeos.cc @@ -142,11 +142,11 @@ void WifiDataProviderChromeOs::ScheduleStart() { bool WifiDataProviderChromeOs::GetAccessPointData( WifiData::AccessPointDataSet* result) { chromeos::WifiAccessPointVector access_points; - if (!chromeos::GeolocationHandler::Get()->wifi_enabled()) + if (!chromeos::NetworkHandler::Get()->geolocation_handler()->wifi_enabled()) return false; int64 age_ms = 0; - if (!chromeos::GeolocationHandler::Get()->GetWifiAccessPoints( - &access_points, &age_ms)) { + if (!chromeos::NetworkHandler::Get()->geolocation_handler()-> + GetWifiAccessPoints(&access_points, &age_ms)) { return false; } for (chromeos::WifiAccessPointVector::const_iterator i diff --git a/content/browser/geolocation/wifi_data_provider_chromeos_unittest.cc b/content/browser/geolocation/wifi_data_provider_chromeos_unittest.cc index 66727159a6..272693f10b 100644 --- a/content/browser/geolocation/wifi_data_provider_chromeos_unittest.cc +++ b/content/browser/geolocation/wifi_data_provider_chromeos_unittest.cc @@ -21,7 +21,7 @@ class GeolocationChromeOsWifiDataProviderTest : public testing::Test { virtual void SetUp() OVERRIDE { chromeos::DBusThreadManager::InitializeWithStub(); - chromeos::GeolocationHandler::Initialize(); + chromeos::NetworkHandler::Initialize(); manager_client_ = chromeos::DBusThreadManager::Get()->GetShillManagerClient(); manager_test_ = manager_client_->GetTestInterface(); @@ -31,7 +31,7 @@ class GeolocationChromeOsWifiDataProviderTest : public testing::Test { virtual void TearDown() OVERRIDE { provider_ = NULL; - chromeos::GeolocationHandler::Shutdown(); + chromeos::NetworkHandler::Shutdown(); chromeos::DBusThreadManager::Shutdown(); } diff --git a/content/browser/gpu/browser_gpu_channel_host_factory.cc b/content/browser/gpu/browser_gpu_channel_host_factory.cc index 00ab6c3e24..7cef1f0015 100644 --- a/content/browser/gpu/browser_gpu_channel_host_factory.cc +++ b/content/browser/gpu/browser_gpu_channel_host_factory.cc @@ -237,7 +237,7 @@ void BrowserGpuChannelHostFactory::EstablishGpuChannelOnIO( void BrowserGpuChannelHostFactory::GpuChannelEstablishedOnIO( EstablishRequest* request, const IPC::ChannelHandle& channel_handle, - const GPUInfo& gpu_info) { + const gpu::GPUInfo& gpu_info) { if (channel_handle.name.empty() && request->reused_gpu_process) { // We failed after re-using the GPU process, but it may have died in the // mean time. Retry to have a chance to create a fresh GPU process. diff --git a/content/browser/gpu/browser_gpu_channel_host_factory.h b/content/browser/gpu/browser_gpu_channel_host_factory.h index 2d3c02148c..5a28fade3c 100644 --- a/content/browser/gpu/browser_gpu_channel_host_factory.h +++ b/content/browser/gpu/browser_gpu_channel_host_factory.h @@ -63,7 +63,7 @@ class BrowserGpuChannelHostFactory : public GpuChannelHostFactory { int gpu_host_id; bool reused_gpu_process; IPC::ChannelHandle channel_handle; - GPUInfo gpu_info; + gpu::GPUInfo gpu_info; }; BrowserGpuChannelHostFactory(); @@ -87,7 +87,7 @@ class BrowserGpuChannelHostFactory : public GpuChannelHostFactory { void GpuChannelEstablishedOnIO( EstablishRequest* request, const IPC::ChannelHandle& channel_handle, - const GPUInfo& gpu_info); + const gpu::GPUInfo& gpu_info); static void AddFilterOnIO( int gpu_host_id, scoped_refptr<IPC::ChannelProxy::MessageFilter> filter); diff --git a/content/browser/gpu/compositor_util.cc b/content/browser/gpu/compositor_util.cc index 0b34932ae8..a0cf1e21a2 100644 --- a/content/browser/gpu/compositor_util.cc +++ b/content/browser/gpu/compositor_util.cc @@ -9,7 +9,7 @@ #include "content/public/browser/gpu_data_manager.h" #include "content/public/common/content_constants.h" #include "content/public/common/content_switches.h" -#include "content/public/common/gpu_feature_type.h" +#include "gpu/config/gpu_feature_type.h" namespace content { @@ -21,7 +21,8 @@ bool CanDoAcceleratedCompositing() { // Don't run the field trial if gpu access has been blocked or // accelerated compositing is blacklisted. if (!manager->GpuAccessAllowed(NULL) || - manager->IsFeatureBlacklisted(GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING)) + manager->IsFeatureBlacklisted( + gpu::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING)) return false; // Check for SwiftShader. @@ -37,7 +38,7 @@ bool CanDoAcceleratedCompositing() { bool IsForceCompositingModeBlacklisted() { return GpuDataManager::GetInstance()->IsFeatureBlacklisted( - GPU_FEATURE_TYPE_FORCE_COMPOSITING_MODE); + gpu::GPU_FEATURE_TYPE_FORCE_COMPOSITING_MODE); } } // namespace diff --git a/content/browser/gpu/gpu_blacklist.cc b/content/browser/gpu/gpu_blacklist.cc deleted file mode 100644 index c8fcbfabe9..0000000000 --- a/content/browser/gpu/gpu_blacklist.cc +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/browser/gpu/gpu_blacklist.h" - -#include "content/public/common/gpu_feature_type.h" - -namespace content { - -GpuBlacklist::GpuBlacklist() - : GpuControlList() { -} - -GpuBlacklist::~GpuBlacklist() { -} - -// static -GpuBlacklist* GpuBlacklist::Create() { - GpuBlacklist* list = new GpuBlacklist(); - list->AddSupportedFeature("accelerated_2d_canvas", - GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS); - list->AddSupportedFeature("accelerated_compositing", - GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING); - list->AddSupportedFeature("webgl", - GPU_FEATURE_TYPE_WEBGL); - list->AddSupportedFeature("multisampling", - GPU_FEATURE_TYPE_MULTISAMPLING); - list->AddSupportedFeature("flash_3d", - GPU_FEATURE_TYPE_FLASH3D); - list->AddSupportedFeature("flash_stage3d", - GPU_FEATURE_TYPE_FLASH_STAGE3D); - list->AddSupportedFeature("flash_stage3d_baseline", - GPU_FEATURE_TYPE_FLASH_STAGE3D_BASELINE); - list->AddSupportedFeature("texture_sharing", - GPU_FEATURE_TYPE_TEXTURE_SHARING); - list->AddSupportedFeature("accelerated_video_decode", - GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE); - list->AddSupportedFeature("3d_css", - GPU_FEATURE_TYPE_3D_CSS); - list->AddSupportedFeature("accelerated_video", - GPU_FEATURE_TYPE_ACCELERATED_VIDEO); - list->AddSupportedFeature("panel_fitting", - GPU_FEATURE_TYPE_PANEL_FITTING); - list->AddSupportedFeature("force_compositing_mode", - GPU_FEATURE_TYPE_FORCE_COMPOSITING_MODE); - list->set_supports_feature_type_all(true); - return list; -} - -} // namespace content diff --git a/content/browser/gpu/gpu_blacklist.h b/content/browser/gpu/gpu_blacklist.h deleted file mode 100644 index 331693d25f..0000000000 --- a/content/browser/gpu/gpu_blacklist.h +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_BROWSER_GPU_GPU_BLACKLIST_H_ -#define CONTENT_BROWSER_GPU_GPU_BLACKLIST_H_ - -#include <string> - -#include "content/browser/gpu/gpu_control_list.h" - -namespace content { - -class CONTENT_EXPORT GpuBlacklist : public GpuControlList { - public: - virtual ~GpuBlacklist(); - - static GpuBlacklist* Create(); - - private: - GpuBlacklist(); - - DISALLOW_COPY_AND_ASSIGN(GpuBlacklist); -}; - -} // namespace content - -#endif // CONTENT_BROWSER_GPU_GPU_BLACKLIST_H_ diff --git a/content/browser/gpu/gpu_blacklist_unittest.cc b/content/browser/gpu/gpu_blacklist_unittest.cc deleted file mode 100644 index 89c0b100b7..0000000000 --- a/content/browser/gpu/gpu_blacklist_unittest.cc +++ /dev/null @@ -1,160 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/base_paths.h" -#include "base/file_util.h" -#include "base/files/file_path.h" -#include "base/memory/scoped_ptr.h" -#include "base/path_service.h" -#include "content/browser/gpu/gpu_blacklist.h" -#include "content/public/common/gpu_feature_type.h" -#include "content/public/common/gpu_info.h" -#include "testing/gtest/include/gtest/gtest.h" - -const char kOsVersion[] = "10.6.4"; - -namespace content { - -class GpuBlacklistTest : public testing::Test { - public: - GpuBlacklistTest() { } - - virtual ~GpuBlacklistTest() { } - - const GPUInfo& gpu_info() const { - return gpu_info_; - } - - void RunFeatureTest( - const std::string feature_name, GpuFeatureType feature_type) { - const std::string json = - "{\n" - " \"name\": \"gpu blacklist\",\n" - " \"version\": \"0.1\",\n" - " \"entries\": [\n" - " {\n" - " \"id\": 1,\n" - " \"os\": {\n" - " \"type\": \"macosx\"\n" - " },\n" - " \"vendor_id\": \"0x10de\",\n" - " \"device_id\": [\"0x0640\"],\n" - " \"features\": [\n" - " \"" + - feature_name + - "\"\n" - " ]\n" - " }\n" - " ]\n" - "}"; - - scoped_ptr<GpuBlacklist> blacklist(GpuBlacklist::Create()); - EXPECT_TRUE(blacklist->LoadList(json, GpuBlacklist::kAllOs)); - std::set<int> type = blacklist->MakeDecision( - GpuBlacklist::kOsMacosx, kOsVersion, gpu_info()); - EXPECT_EQ(1u, type.size()); - EXPECT_EQ(1u, type.count(feature_type)); - } - - protected: - virtual void SetUp() { - gpu_info_.gpu.vendor_id = 0x10de; - gpu_info_.gpu.device_id = 0x0640; - gpu_info_.driver_vendor = "NVIDIA"; - gpu_info_.driver_version = "1.6.18"; - gpu_info_.driver_date = "7-14-2009"; - gpu_info_.machine_model = "MacBookPro 7.1"; - gpu_info_.gl_vendor = "NVIDIA Corporation"; - gpu_info_.gl_renderer = "NVIDIA GeForce GT 120 OpenGL Engine"; - gpu_info_.performance_stats.graphics = 5.0; - gpu_info_.performance_stats.gaming = 5.0; - gpu_info_.performance_stats.overall = 5.0; - } - - virtual void TearDown() { - } - - private: - GPUInfo gpu_info_; -}; - -TEST_F(GpuBlacklistTest, CurrentBlacklistValidation) { - base::FilePath data_file; - ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &data_file)); - data_file = - data_file.Append(FILE_PATH_LITERAL("content")) - .Append(FILE_PATH_LITERAL("browser")) - .Append(FILE_PATH_LITERAL("gpu")) - .Append(FILE_PATH_LITERAL("software_rendering_list.json")); - ASSERT_TRUE(file_util::PathExists(data_file)); - int64 data_file_size64 = 0; - ASSERT_TRUE(file_util::GetFileSize(data_file, &data_file_size64)); - int data_file_size = static_cast<int>(data_file_size64); - scoped_ptr<char[]> data(new char[data_file_size]); - ASSERT_EQ(data_file_size, - file_util::ReadFile(data_file, data.get(), data_file_size)); - std::string json_string(data.get(), data_file_size); - scoped_ptr<GpuBlacklist> blacklist(GpuBlacklist::Create()); - EXPECT_TRUE(blacklist->LoadList(json_string, GpuBlacklist::kAllOs)); - EXPECT_FALSE(blacklist->contains_unknown_fields()); -} - -#define GPU_BLACKLIST_FEATURE_TEST(test_name, feature_name, feature_type) \ -TEST_F(GpuBlacklistTest, test_name) { \ - RunFeatureTest(feature_name, feature_type); \ -} - -GPU_BLACKLIST_FEATURE_TEST(Accelerated2DCanvas, - "accelerated_2d_canvas", - GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS) - -GPU_BLACKLIST_FEATURE_TEST(AcceleratedCompositing, - "accelerated_compositing", - GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING) - -GPU_BLACKLIST_FEATURE_TEST(WebGL, - "webgl", - GPU_FEATURE_TYPE_WEBGL) - -GPU_BLACKLIST_FEATURE_TEST(Multisampling, - "multisampling", - GPU_FEATURE_TYPE_MULTISAMPLING) - -GPU_BLACKLIST_FEATURE_TEST(Flash3D, - "flash_3d", - GPU_FEATURE_TYPE_FLASH3D) - -GPU_BLACKLIST_FEATURE_TEST(FlashStage3D, - "flash_stage3d", - GPU_FEATURE_TYPE_FLASH_STAGE3D) - -GPU_BLACKLIST_FEATURE_TEST(FlashStage3DBaseline, - "flash_stage3d_baseline", - GPU_FEATURE_TYPE_FLASH_STAGE3D_BASELINE) - -GPU_BLACKLIST_FEATURE_TEST(TextureSharing, - "texture_sharing", - GPU_FEATURE_TYPE_TEXTURE_SHARING) - -GPU_BLACKLIST_FEATURE_TEST(AcceleratedVideoDecode, - "accelerated_video_decode", - GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE) - -GPU_BLACKLIST_FEATURE_TEST(Css3D, - "3d_css", - GPU_FEATURE_TYPE_3D_CSS) - -GPU_BLACKLIST_FEATURE_TEST(AcceleratedVideo, - "accelerated_video", - GPU_FEATURE_TYPE_ACCELERATED_VIDEO) - -GPU_BLACKLIST_FEATURE_TEST(PanelFitting, - "panel_fitting", - GPU_FEATURE_TYPE_PANEL_FITTING) - -GPU_BLACKLIST_FEATURE_TEST(ForceCompositingMode, - "force_compositing_mode", - GPU_FEATURE_TYPE_FORCE_COMPOSITING_MODE) - -} // namespace content diff --git a/content/browser/gpu/gpu_control_list.cc b/content/browser/gpu/gpu_control_list.cc deleted file mode 100644 index 0f2b7b3881..0000000000 --- a/content/browser/gpu/gpu_control_list.cc +++ /dev/null @@ -1,1415 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/browser/gpu/gpu_control_list.h" - -#include "base/cpu.h" -#include "base/json/json_reader.h" -#include "base/logging.h" -#include "base/string_util.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/string_split.h" -#include "base/sys_info.h" -#include "content/browser/gpu/gpu_util.h" -#include "content/public/common/gpu_info.h" - -namespace content { -namespace { - -// Break a version string into segments. Return true if each segment is -// a valid number. -bool ProcessVersionString(const std::string& version_string, - char splitter, - std::vector<std::string>* version) { - DCHECK(version); - base::SplitString(version_string, splitter, version); - if (version->size() == 0) - return false; - // If the splitter is '-', we assume it's a date with format "mm-dd-yyyy"; - // we split it into the order of "yyyy", "mm", "dd". - if (splitter == '-') { - std::string year = (*version)[version->size() - 1]; - for (int i = version->size() - 1; i > 0; --i) { - (*version)[i] = (*version)[i - 1]; - } - (*version)[0] = year; - } - for (size_t i = 0; i < version->size(); ++i) { - unsigned num = 0; - if (!base::StringToUint((*version)[i], &num)) - return false; - } - return true; -} - -// Compare two number strings using numerical ordering. -// Return 0 if number = number_ref, -// 1 if number > number_ref, -// -1 if number < number_ref. -int CompareNumericalNumberStrings( - const std::string& number, const std::string& number_ref) { - unsigned value1 = 0; - unsigned value2 = 0; - bool valid = base::StringToUint(number, &value1); - DCHECK(valid); - valid = base::StringToUint(number_ref, &value2); - DCHECK(valid); - if (value1 == value2) - return 0; - if (value1 > value2) - return 1; - return -1; -} - -// Compare two number strings using lexical ordering. -// Return 0 if number = number_ref, -// 1 if number > number_ref, -// -1 if number < number_ref. -// We only compare as many digits as number_ref contains. -// If number_ref is xxx, it's considered as xxx* -// For example: CompareLexicalNumberStrings("121", "12") returns 0, -// CompareLexicalNumberStrings("12", "121") returns -1. -int CompareLexicalNumberStrings( - const std::string& number, const std::string& number_ref) { - for (size_t i = 0; i < number_ref.length(); ++i) { - unsigned value1 = 0; - if (i < number.length()) - value1 = number[i] - '0'; - unsigned value2 = number_ref[i] - '0'; - if (value1 > value2) - return 1; - if (value1 < value2) - return -1; - } - return 0; -} - -bool GpuUnmatched(uint32 vendor_id, const std::vector<uint32>& device_id_list, - const GPUInfo::GPUDevice& gpu) { - if (vendor_id == 0) - return false; - if (vendor_id != gpu.vendor_id) - return true; - bool device_specified = false; - for (size_t i = 0; i < device_id_list.size(); ++i) { - if (device_id_list[i] == 0) - continue; - if (device_id_list[i] == gpu.device_id) - return false; - device_specified = true; - } - return device_specified; -} - -const char kMultiGpuStyleStringAMDSwitchable[] = "amd_switchable"; -const char kMultiGpuStyleStringOptimus[] = "optimus"; - -const char kMultiGpuCategoryStringPrimary[] = "primary"; -const char kMultiGpuCategoryStringSecondary[] = "secondary"; -const char kMultiGpuCategoryStringAny[] = "any"; - -const char kVersionStyleStringNumerical[] = "numerical"; -const char kVersionStyleStringLexical[] = "lexical"; - -const char kOp[] = "op"; - -} // namespace anonymous - -GpuControlList::VersionInfo::VersionInfo( - const std::string& version_op, - const std::string& version_style, - const std::string& version_string, - const std::string& version_string2) - : version_style_(kVersionStyleNumerical) { - op_ = StringToNumericOp(version_op); - if (op_ == kUnknown || op_ == kAny) - return; - version_style_ = StringToVersionStyle(version_style); - if (!ProcessVersionString(version_string, '.', &version_)) { - op_ = kUnknown; - return; - } - if (op_ == kBetween) { - if (!ProcessVersionString(version_string2, '.', &version2_)) - op_ = kUnknown; - } -} - -GpuControlList::VersionInfo::~VersionInfo() { -} - -bool GpuControlList::VersionInfo::Contains( - const std::string& version_string) const { - return Contains(version_string, '.'); -} - -bool GpuControlList::VersionInfo::Contains( - const std::string& version_string, char splitter) const { - if (op_ == kUnknown) - return false; - if (op_ == kAny) - return true; - std::vector<std::string> version; - if (!ProcessVersionString(version_string, splitter, &version)) - return false; - int relation = Compare(version, version_, version_style_); - if (op_ == kEQ) - return (relation == 0); - else if (op_ == kLT) - return (relation < 0); - else if (op_ == kLE) - return (relation <= 0); - else if (op_ == kGT) - return (relation > 0); - else if (op_ == kGE) - return (relation >= 0); - // op_ == kBetween - if (relation < 0) - return false; - return Compare(version, version2_, version_style_) <= 0; -} - -bool GpuControlList::VersionInfo::IsValid() const { - return (op_ != kUnknown && version_style_ != kVersionStyleUnknown); -} - -bool GpuControlList::VersionInfo::IsLexical() const { - return version_style_ == kVersionStyleLexical; -} - -// static -int GpuControlList::VersionInfo::Compare( - const std::vector<std::string>& version, - const std::vector<std::string>& version_ref, - VersionStyle version_style) { - DCHECK(version.size() > 0 && version_ref.size() > 0); - DCHECK(version_style != kVersionStyleUnknown); - for (size_t i = 0; i < version_ref.size(); ++i) { - if (i >= version.size()) - return 0; - int ret = 0; - // We assume both versions are checked by ProcessVersionString(). - if (i > 0 && version_style == kVersionStyleLexical) - ret = CompareLexicalNumberStrings(version[i], version_ref[i]); - else - ret = CompareNumericalNumberStrings(version[i], version_ref[i]); - if (ret != 0) - return ret; - } - return 0; -} - -// static -GpuControlList::VersionInfo::VersionStyle -GpuControlList::VersionInfo::StringToVersionStyle( - const std::string& version_style) { - if (version_style.empty() || version_style == kVersionStyleStringNumerical) - return kVersionStyleNumerical; - if (version_style == kVersionStyleStringLexical) - return kVersionStyleLexical; - return kVersionStyleUnknown; -} - -GpuControlList::OsInfo::OsInfo(const std::string& os, - const std::string& version_op, - const std::string& version_string, - const std::string& version_string2) { - type_ = StringToOsType(os); - if (type_ != kOsUnknown) { - version_info_.reset(new VersionInfo( - version_op, std::string(), version_string, version_string2)); - } -} - -GpuControlList::OsInfo::~OsInfo() {} - -bool GpuControlList::OsInfo::Contains(OsType type, - const std::string& version) const { - if (!IsValid()) - return false; - if (type_ != type && type_ != kOsAny) - return false; - return version_info_->Contains(version); -} - -bool GpuControlList::OsInfo::IsValid() const { - return type_ != kOsUnknown && version_info_->IsValid(); -} - -GpuControlList::OsType GpuControlList::OsInfo::type() const { - return type_; -} - -GpuControlList::OsType GpuControlList::OsInfo::StringToOsType( - const std::string& os) { - if (os == "win") - return kOsWin; - else if (os == "macosx") - return kOsMacosx; - else if (os == "android") - return kOsAndroid; - else if (os == "linux") - return kOsLinux; - else if (os == "chromeos") - return kOsChromeOS; - else if (os == "any") - return kOsAny; - return kOsUnknown; -} - -GpuControlList::MachineModelInfo::MachineModelInfo( - const std::string& name_op, - const std::string& name_value, - const std::string& version_op, - const std::string& version_string, - const std::string& version_string2) { - name_info_.reset(new StringInfo(name_op, name_value)); - version_info_.reset(new VersionInfo( - version_op, std::string(), version_string, version_string2)); -} - -GpuControlList::MachineModelInfo::~MachineModelInfo() {} - -bool GpuControlList::MachineModelInfo::Contains( - const std::string& name, const std::string& version) const { - if (!IsValid()) - return false; - if (!name_info_->Contains(name)) - return false; - return version_info_->Contains(version); -} - -bool GpuControlList::MachineModelInfo::IsValid() const { - return name_info_->IsValid() && version_info_->IsValid(); -} - -GpuControlList::StringInfo::StringInfo(const std::string& string_op, - const std::string& string_value) { - op_ = StringToOp(string_op); - value_ = StringToLowerASCII(string_value); -} - -bool GpuControlList::StringInfo::Contains(const std::string& value) const { - std::string my_value = StringToLowerASCII(value); - switch (op_) { - case kContains: - return strstr(my_value.c_str(), value_.c_str()) != NULL; - case kBeginWith: - return StartsWithASCII(my_value, value_, false); - case kEndWith: - return EndsWith(my_value, value_, false); - case kEQ: - return value_ == my_value; - default: - return false; - } -} - -bool GpuControlList::StringInfo::IsValid() const { - return op_ != kUnknown; -} - -GpuControlList::StringInfo::Op GpuControlList::StringInfo::StringToOp( - const std::string& string_op) { - if (string_op == "=") - return kEQ; - else if (string_op == "contains") - return kContains; - else if (string_op == "beginwith") - return kBeginWith; - else if (string_op == "endwith") - return kEndWith; - return kUnknown; -} - -GpuControlList::FloatInfo::FloatInfo(const std::string& float_op, - const std::string& float_value, - const std::string& float_value2) - : op_(kUnknown), - value_(0.f), - value2_(0.f) { - op_ = StringToNumericOp(float_op); - if (op_ == kAny) - return; - double dvalue = 0; - if (!base::StringToDouble(float_value, &dvalue)) { - op_ = kUnknown; - return; - } - value_ = static_cast<float>(dvalue); - if (op_ == kBetween) { - if (!base::StringToDouble(float_value2, &dvalue)) { - op_ = kUnknown; - return; - } - value2_ = static_cast<float>(dvalue); - } -} - -bool GpuControlList::FloatInfo::Contains(float value) const { - if (op_ == kUnknown) - return false; - if (op_ == kAny) - return true; - if (op_ == kEQ) - return (value == value_); - if (op_ == kLT) - return (value < value_); - if (op_ == kLE) - return (value <= value_); - if (op_ == kGT) - return (value > value_); - if (op_ == kGE) - return (value >= value_); - DCHECK(op_ == kBetween); - return ((value_ <= value && value <= value2_) || - (value2_ <= value && value <= value_)); -} - -bool GpuControlList::FloatInfo::IsValid() const { - return op_ != kUnknown; -} - -GpuControlList::IntInfo::IntInfo(const std::string& int_op, - const std::string& int_value, - const std::string& int_value2) - : op_(kUnknown), - value_(0), - value2_(0) { - op_ = StringToNumericOp(int_op); - if (op_ == kAny) - return; - if (!base::StringToInt(int_value, &value_)) { - op_ = kUnknown; - return; - } - if (op_ == kBetween && - !base::StringToInt(int_value2, &value2_)) - op_ = kUnknown; -} - -bool GpuControlList::IntInfo::Contains(int value) const { - if (op_ == kUnknown) - return false; - if (op_ == kAny) - return true; - if (op_ == kEQ) - return (value == value_); - if (op_ == kLT) - return (value < value_); - if (op_ == kLE) - return (value <= value_); - if (op_ == kGT) - return (value > value_); - if (op_ == kGE) - return (value >= value_); - DCHECK(op_ == kBetween); - return ((value_ <= value && value <= value2_) || - (value2_ <= value && value <= value_)); -} - -bool GpuControlList::IntInfo::IsValid() const { - return op_ != kUnknown; -} - -// static -GpuControlList::ScopedGpuControlListEntry -GpuControlList::GpuControlListEntry::GetEntryFromValue( - const base::DictionaryValue* value, bool top_level, - const FeatureMap& feature_map, - bool supports_feature_type_all) { - DCHECK(value); - ScopedGpuControlListEntry entry(new GpuControlListEntry()); - - size_t dictionary_entry_count = 0; - - if (top_level) { - uint32 id; - if (!value->GetInteger("id", reinterpret_cast<int*>(&id)) || - !entry->SetId(id)) { - LOG(WARNING) << "Malformed id entry " << entry->id(); - return NULL; - } - dictionary_entry_count++; - - bool disabled; - if (value->GetBoolean("disabled", &disabled)) { - entry->SetDisabled(disabled); - dictionary_entry_count++; - } - } - - std::string description; - if (value->GetString("description", &description)) { - entry->description_ = description; - dictionary_entry_count++; - } else { - entry->description_ = "The GPU is unavailable for an unexplained reason."; - } - - const base::ListValue* cr_bugs; - if (value->GetList("cr_bugs", &cr_bugs)) { - for (size_t i = 0; i < cr_bugs->GetSize(); ++i) { - int bug_id; - if (cr_bugs->GetInteger(i, &bug_id)) { - entry->cr_bugs_.push_back(bug_id); - } else { - LOG(WARNING) << "Malformed cr_bugs entry " << entry->id(); - return NULL; - } - } - dictionary_entry_count++; - } - - const base::ListValue* webkit_bugs; - if (value->GetList("webkit_bugs", &webkit_bugs)) { - for (size_t i = 0; i < webkit_bugs->GetSize(); ++i) { - int bug_id; - if (webkit_bugs->GetInteger(i, &bug_id)) { - entry->webkit_bugs_.push_back(bug_id); - } else { - LOG(WARNING) << "Malformed webkit_bugs entry " << entry->id(); - return NULL; - } - } - dictionary_entry_count++; - } - - const base::DictionaryValue* os_value = NULL; - if (value->GetDictionary("os", &os_value)) { - std::string os_type; - std::string os_version_op = "any"; - std::string os_version_string; - std::string os_version_string2; - os_value->GetString("type", &os_type); - const base::DictionaryValue* os_version_value = NULL; - if (os_value->GetDictionary("version", &os_version_value)) { - os_version_value->GetString(kOp, &os_version_op); - os_version_value->GetString("number", &os_version_string); - os_version_value->GetString("number2", &os_version_string2); - } - if (!entry->SetOsInfo(os_type, os_version_op, os_version_string, - os_version_string2)) { - LOG(WARNING) << "Malformed os entry " << entry->id(); - return NULL; - } - dictionary_entry_count++; - } - - std::string vendor_id; - if (value->GetString("vendor_id", &vendor_id)) { - if (!entry->SetVendorId(vendor_id)) { - LOG(WARNING) << "Malformed vendor_id entry " << entry->id(); - return NULL; - } - dictionary_entry_count++; - } - - const base::ListValue* device_id_list; - if (value->GetList("device_id", &device_id_list)) { - for (size_t i = 0; i < device_id_list->GetSize(); ++i) { - std::string device_id; - if (!device_id_list->GetString(i, &device_id) || - !entry->AddDeviceId(device_id)) { - LOG(WARNING) << "Malformed device_id entry " << entry->id(); - return NULL; - } - } - dictionary_entry_count++; - } - - std::string multi_gpu_style; - if (value->GetString("multi_gpu_style", &multi_gpu_style)) { - if (!entry->SetMultiGpuStyle(multi_gpu_style)) { - LOG(WARNING) << "Malformed multi_gpu_style entry " << entry->id(); - return NULL; - } - dictionary_entry_count++; - } - - std::string multi_gpu_category; - if (value->GetString("multi_gpu_category", &multi_gpu_category)) { - if (!entry->SetMultiGpuCategory(multi_gpu_category)) { - LOG(WARNING) << "Malformed multi_gpu_category entry " << entry->id(); - return NULL; - } - dictionary_entry_count++; - } - - const base::DictionaryValue* driver_vendor_value = NULL; - if (value->GetDictionary("driver_vendor", &driver_vendor_value)) { - std::string vendor_op; - std::string vendor_value; - driver_vendor_value->GetString(kOp, &vendor_op); - driver_vendor_value->GetString("value", &vendor_value); - if (!entry->SetDriverVendorInfo(vendor_op, vendor_value)) { - LOG(WARNING) << "Malformed driver_vendor entry " << entry->id(); - return NULL; - } - dictionary_entry_count++; - } - - const base::DictionaryValue* driver_version_value = NULL; - if (value->GetDictionary("driver_version", &driver_version_value)) { - std::string driver_version_op = "any"; - std::string driver_version_style; - std::string driver_version_string; - std::string driver_version_string2; - driver_version_value->GetString(kOp, &driver_version_op); - driver_version_value->GetString("style", &driver_version_style); - driver_version_value->GetString("number", &driver_version_string); - driver_version_value->GetString("number2", &driver_version_string2); - if (!entry->SetDriverVersionInfo(driver_version_op, - driver_version_style, - driver_version_string, - driver_version_string2)) { - LOG(WARNING) << "Malformed driver_version entry " << entry->id(); - return NULL; - } - dictionary_entry_count++; - } - - const base::DictionaryValue* driver_date_value = NULL; - if (value->GetDictionary("driver_date", &driver_date_value)) { - std::string driver_date_op = "any"; - std::string driver_date_string; - std::string driver_date_string2; - driver_date_value->GetString(kOp, &driver_date_op); - driver_date_value->GetString("number", &driver_date_string); - driver_date_value->GetString("number2", &driver_date_string2); - if (!entry->SetDriverDateInfo(driver_date_op, driver_date_string, - driver_date_string2)) { - LOG(WARNING) << "Malformed driver_date entry " << entry->id(); - return NULL; - } - dictionary_entry_count++; - } - - const base::DictionaryValue* gl_vendor_value = NULL; - if (value->GetDictionary("gl_vendor", &gl_vendor_value)) { - std::string vendor_op; - std::string vendor_value; - gl_vendor_value->GetString(kOp, &vendor_op); - gl_vendor_value->GetString("value", &vendor_value); - if (!entry->SetGLVendorInfo(vendor_op, vendor_value)) { - LOG(WARNING) << "Malformed gl_vendor entry " << entry->id(); - return NULL; - } - dictionary_entry_count++; - } - - const base::DictionaryValue* gl_renderer_value = NULL; - if (value->GetDictionary("gl_renderer", &gl_renderer_value)) { - std::string renderer_op; - std::string renderer_value; - gl_renderer_value->GetString(kOp, &renderer_op); - gl_renderer_value->GetString("value", &renderer_value); - if (!entry->SetGLRendererInfo(renderer_op, renderer_value)) { - LOG(WARNING) << "Malformed gl_renderer entry " << entry->id(); - return NULL; - } - dictionary_entry_count++; - } - - const base::DictionaryValue* gl_extensions_value = NULL; - if (value->GetDictionary("gl_extensions", &gl_extensions_value)) { - std::string extensions_op; - std::string extensions_value; - gl_extensions_value->GetString(kOp, &extensions_op); - gl_extensions_value->GetString("value", &extensions_value); - if (!entry->SetGLExtensionsInfo(extensions_op, extensions_value)) { - LOG(WARNING) << "Malformed gl_extensions entry " << entry->id(); - return NULL; - } - dictionary_entry_count++; - } - - const base::DictionaryValue* cpu_brand_value = NULL; - if (value->GetDictionary("cpu_info", &cpu_brand_value)) { - std::string cpu_op; - std::string cpu_value; - cpu_brand_value->GetString(kOp, &cpu_op); - cpu_brand_value->GetString("value", &cpu_value); - if (!entry->SetCpuBrand(cpu_op, cpu_value)) { - LOG(WARNING) << "Malformed cpu_brand entry " << entry->id(); - return NULL; - } - dictionary_entry_count++; - } - - const base::DictionaryValue* perf_graphics_value = NULL; - if (value->GetDictionary("perf_graphics", &perf_graphics_value)) { - std::string op; - std::string float_value; - std::string float_value2; - perf_graphics_value->GetString(kOp, &op); - perf_graphics_value->GetString("value", &float_value); - perf_graphics_value->GetString("value2", &float_value2); - if (!entry->SetPerfGraphicsInfo(op, float_value, float_value2)) { - LOG(WARNING) << "Malformed perf_graphics entry " << entry->id(); - return NULL; - } - dictionary_entry_count++; - } - - const base::DictionaryValue* perf_gaming_value = NULL; - if (value->GetDictionary("perf_gaming", &perf_gaming_value)) { - std::string op; - std::string float_value; - std::string float_value2; - perf_gaming_value->GetString(kOp, &op); - perf_gaming_value->GetString("value", &float_value); - perf_gaming_value->GetString("value2", &float_value2); - if (!entry->SetPerfGamingInfo(op, float_value, float_value2)) { - LOG(WARNING) << "Malformed perf_gaming entry " << entry->id(); - return NULL; - } - dictionary_entry_count++; - } - - const base::DictionaryValue* perf_overall_value = NULL; - if (value->GetDictionary("perf_overall", &perf_overall_value)) { - std::string op; - std::string float_value; - std::string float_value2; - perf_overall_value->GetString(kOp, &op); - perf_overall_value->GetString("value", &float_value); - perf_overall_value->GetString("value2", &float_value2); - if (!entry->SetPerfOverallInfo(op, float_value, float_value2)) { - LOG(WARNING) << "Malformed perf_overall entry " << entry->id(); - return NULL; - } - dictionary_entry_count++; - } - - const base::DictionaryValue* machine_model_value = NULL; - if (value->GetDictionary("machine_model", &machine_model_value)) { - std::string name_op; - std::string name_value; - const base::DictionaryValue* name = NULL; - if (machine_model_value->GetDictionary("name", &name)) { - name->GetString(kOp, &name_op); - name->GetString("value", &name_value); - } - - std::string version_op = "any"; - std::string version_string; - std::string version_string2; - const base::DictionaryValue* version_value = NULL; - if (machine_model_value->GetDictionary("version", &version_value)) { - version_value->GetString(kOp, &version_op); - version_value->GetString("number", &version_string); - version_value->GetString("number2", &version_string2); - } - if (!entry->SetMachineModelInfo( - name_op, name_value, version_op, version_string, version_string2)) { - LOG(WARNING) << "Malformed machine_model entry " << entry->id(); - return NULL; - } - dictionary_entry_count++; - } - - const base::DictionaryValue* gpu_count_value = NULL; - if (value->GetDictionary("gpu_count", &gpu_count_value)) { - std::string op; - std::string int_value; - std::string int_value2; - gpu_count_value->GetString(kOp, &op); - gpu_count_value->GetString("value", &int_value); - gpu_count_value->GetString("value2", &int_value2); - if (!entry->SetGpuCountInfo(op, int_value, int_value2)) { - LOG(WARNING) << "Malformed gpu_count entry " << entry->id(); - return NULL; - } - dictionary_entry_count++; - } - - if (top_level) { - const base::ListValue* feature_value = NULL; - if (value->GetList("features", &feature_value)) { - std::vector<std::string> feature_list; - for (size_t i = 0; i < feature_value->GetSize(); ++i) { - std::string feature; - if (feature_value->GetString(i, &feature)) { - feature_list.push_back(feature); - } else { - LOG(WARNING) << "Malformed feature entry " << entry->id(); - return NULL; - } - } - if (!entry->SetFeatures( - feature_list, feature_map, supports_feature_type_all)) { - LOG(WARNING) << "Malformed feature entry " << entry->id(); - return NULL; - } - dictionary_entry_count++; - } - } - - if (top_level) { - const base::ListValue* exception_list_value = NULL; - if (value->GetList("exceptions", &exception_list_value)) { - for (size_t i = 0; i < exception_list_value->GetSize(); ++i) { - const base::DictionaryValue* exception_value = NULL; - if (!exception_list_value->GetDictionary(i, &exception_value)) { - LOG(WARNING) << "Malformed exceptions entry " << entry->id(); - return NULL; - } - ScopedGpuControlListEntry exception(GetEntryFromValue( - exception_value, false, feature_map, supports_feature_type_all)); - if (exception == NULL) { - LOG(WARNING) << "Malformed exceptions entry " << entry->id(); - return NULL; - } - if (exception->contains_unknown_fields_) { - LOG(WARNING) << "Exception with unknown fields " << entry->id(); - entry->contains_unknown_fields_ = true; - } else { - entry->AddException(exception); - } - } - dictionary_entry_count++; - } - - const base::DictionaryValue* browser_version_value = NULL; - // browser_version is processed in LoadGpuControlList(). - if (value->GetDictionary("browser_version", &browser_version_value)) - dictionary_entry_count++; - } - - if (value->size() != dictionary_entry_count) { - LOG(WARNING) << "Entry with unknown fields " << entry->id(); - entry->contains_unknown_fields_ = true; - } - return entry; -} - -GpuControlList::GpuControlListEntry::GpuControlListEntry() - : id_(0), - disabled_(false), - vendor_id_(0), - multi_gpu_style_(kMultiGpuStyleNone), - multi_gpu_category_(kMultiGpuCategoryPrimary), - contains_unknown_fields_(false), - contains_unknown_features_(false) { -} - -GpuControlList::GpuControlListEntry::~GpuControlListEntry() { } - -bool GpuControlList::GpuControlListEntry::SetId(uint32 id) { - if (id != 0) { - id_ = id; - return true; - } - return false; -} - -void GpuControlList::GpuControlListEntry::SetDisabled(bool disabled) { - disabled_ = disabled; -} - -bool GpuControlList::GpuControlListEntry::SetOsInfo( - const std::string& os, - const std::string& version_op, - const std::string& version_string, - const std::string& version_string2) { - os_info_.reset(new OsInfo(os, version_op, version_string, version_string2)); - return os_info_->IsValid(); -} - -bool GpuControlList::GpuControlListEntry::SetVendorId( - const std::string& vendor_id_string) { - vendor_id_ = 0; - return base::HexStringToInt(vendor_id_string, - reinterpret_cast<int*>(&vendor_id_)); -} - -bool GpuControlList::GpuControlListEntry::AddDeviceId( - const std::string& device_id_string) { - uint32 device_id = 0; - if (base::HexStringToInt(device_id_string, - reinterpret_cast<int*>(&device_id))) { - device_id_list_.push_back(device_id); - return true; - } - return false; -} - -bool GpuControlList::GpuControlListEntry::SetMultiGpuStyle( - const std::string& multi_gpu_style_string) { - MultiGpuStyle style = StringToMultiGpuStyle(multi_gpu_style_string); - if (style == kMultiGpuStyleNone) - return false; - multi_gpu_style_ = style; - return true; -} - -bool GpuControlList::GpuControlListEntry::SetMultiGpuCategory( - const std::string& multi_gpu_category_string) { - MultiGpuCategory category = - StringToMultiGpuCategory(multi_gpu_category_string); - if (category == kMultiGpuCategoryNone) - return false; - multi_gpu_category_ = category; - return true; -} - -bool GpuControlList::GpuControlListEntry::SetDriverVendorInfo( - const std::string& vendor_op, - const std::string& vendor_value) { - driver_vendor_info_.reset(new StringInfo(vendor_op, vendor_value)); - return driver_vendor_info_->IsValid(); -} - -bool GpuControlList::GpuControlListEntry::SetDriverVersionInfo( - const std::string& version_op, - const std::string& version_style, - const std::string& version_string, - const std::string& version_string2) { - driver_version_info_.reset(new VersionInfo( - version_op, version_style, version_string, version_string2)); - return driver_version_info_->IsValid(); -} - -bool GpuControlList::GpuControlListEntry::SetDriverDateInfo( - const std::string& date_op, - const std::string& date_string, - const std::string& date_string2) { - driver_date_info_.reset( - new VersionInfo(date_op, std::string(), date_string, date_string2)); - return driver_date_info_->IsValid(); -} - -bool GpuControlList::GpuControlListEntry::SetGLVendorInfo( - const std::string& vendor_op, - const std::string& vendor_value) { - gl_vendor_info_.reset(new StringInfo(vendor_op, vendor_value)); - return gl_vendor_info_->IsValid(); -} - -bool GpuControlList::GpuControlListEntry::SetGLRendererInfo( - const std::string& renderer_op, - const std::string& renderer_value) { - gl_renderer_info_.reset(new StringInfo(renderer_op, renderer_value)); - return gl_renderer_info_->IsValid(); -} - -bool GpuControlList::GpuControlListEntry::SetGLExtensionsInfo( - const std::string& extensions_op, - const std::string& extensions_value) { - gl_extensions_info_.reset(new StringInfo(extensions_op, extensions_value)); - return gl_extensions_info_->IsValid(); -} - -bool GpuControlList::GpuControlListEntry::SetCpuBrand( - const std::string& cpu_op, - const std::string& cpu_value) { - cpu_brand_.reset(new StringInfo(cpu_op, cpu_value)); - return cpu_brand_->IsValid(); -} - -bool GpuControlList::GpuControlListEntry::SetPerfGraphicsInfo( - const std::string& op, - const std::string& float_string, - const std::string& float_string2) { - perf_graphics_info_.reset(new FloatInfo(op, float_string, float_string2)); - return perf_graphics_info_->IsValid(); -} - -bool GpuControlList::GpuControlListEntry::SetPerfGamingInfo( - const std::string& op, - const std::string& float_string, - const std::string& float_string2) { - perf_gaming_info_.reset(new FloatInfo(op, float_string, float_string2)); - return perf_gaming_info_->IsValid(); -} - -bool GpuControlList::GpuControlListEntry::SetPerfOverallInfo( - const std::string& op, - const std::string& float_string, - const std::string& float_string2) { - perf_overall_info_.reset(new FloatInfo(op, float_string, float_string2)); - return perf_overall_info_->IsValid(); -} - -bool GpuControlList::GpuControlListEntry::SetMachineModelInfo( - const std::string& name_op, - const std::string& name_value, - const std::string& version_op, - const std::string& version_string, - const std::string& version_string2) { - machine_model_info_.reset(new MachineModelInfo( - name_op, name_value, version_op, version_string, version_string2)); - return machine_model_info_->IsValid(); -} - -bool GpuControlList::GpuControlListEntry::SetGpuCountInfo( - const std::string& op, - const std::string& int_string, - const std::string& int_string2) { - gpu_count_info_.reset(new IntInfo(op, int_string, int_string2)); - return gpu_count_info_->IsValid(); -} - -bool GpuControlList::GpuControlListEntry::SetFeatures( - const std::vector<std::string>& feature_strings, - const FeatureMap& feature_map, - bool supports_feature_type_all) { - size_t size = feature_strings.size(); - if (size == 0) - return false; - features_.clear(); - for (size_t i = 0; i < size; ++i) { - int feature = 0; - if (supports_feature_type_all && feature_strings[i] == "all") { - for (FeatureMap::const_iterator iter = feature_map.begin(); - iter != feature_map.end(); ++iter) - features_.insert(iter->second); - continue; - } - if (StringToFeature(feature_strings[i], &feature, feature_map)) - features_.insert(feature); - else - contains_unknown_features_ = true; - } - return true; -} - -void GpuControlList::GpuControlListEntry::AddException( - ScopedGpuControlListEntry exception) { - exceptions_.push_back(exception); -} - -// static -GpuControlList::GpuControlListEntry::MultiGpuStyle -GpuControlList::GpuControlListEntry::StringToMultiGpuStyle( - const std::string& style) { - if (style == kMultiGpuStyleStringOptimus) - return kMultiGpuStyleOptimus; - if (style == kMultiGpuStyleStringAMDSwitchable) - return kMultiGpuStyleAMDSwitchable; - return kMultiGpuStyleNone; -} - -// static -GpuControlList::GpuControlListEntry::MultiGpuCategory -GpuControlList::GpuControlListEntry::StringToMultiGpuCategory( - const std::string& category) { - if (category == kMultiGpuCategoryStringPrimary) - return kMultiGpuCategoryPrimary; - if (category == kMultiGpuCategoryStringSecondary) - return kMultiGpuCategorySecondary; - if (category == kMultiGpuCategoryStringAny) - return kMultiGpuCategoryAny; - return kMultiGpuCategoryNone; -} - -bool GpuControlList::GpuControlListEntry::Contains( - OsType os_type, const std::string& os_version, - const GPUInfo& gpu_info) const { - DCHECK(os_type != kOsAny); - if (os_info_.get() != NULL && !os_info_->Contains(os_type, os_version)) - return false; - bool is_not_primary_gpu = - GpuUnmatched(vendor_id_, device_id_list_, gpu_info.gpu); - bool is_not_secondary_gpu = true; - for (size_t i = 0; i < gpu_info.secondary_gpus.size(); ++i) { - is_not_secondary_gpu = is_not_secondary_gpu && - GpuUnmatched(vendor_id_, device_id_list_, gpu_info.secondary_gpus[i]); - } - switch (multi_gpu_category_) { - case kMultiGpuCategoryPrimary: - if (is_not_primary_gpu) - return false; - break; - case kMultiGpuCategorySecondary: - if (is_not_secondary_gpu) - return false; - break; - case kMultiGpuCategoryAny: - if (is_not_primary_gpu && is_not_secondary_gpu) - return false; - break; - case kMultiGpuCategoryNone: - break; - } - switch (multi_gpu_style_) { - case kMultiGpuStyleOptimus: - if (!gpu_info.optimus) - return false; - break; - case kMultiGpuStyleAMDSwitchable: - if (!gpu_info.amd_switchable) - return false; - break; - case kMultiGpuStyleNone: - break; - } - if (driver_vendor_info_.get() != NULL && !gpu_info.driver_vendor.empty() && - !driver_vendor_info_->Contains(gpu_info.driver_vendor)) - return false; - if (driver_version_info_.get() != NULL && !gpu_info.driver_version.empty()) { - if (!driver_version_info_->Contains(gpu_info.driver_version)) - return false; - } - if (driver_date_info_.get() != NULL && !gpu_info.driver_date.empty()) { - if (!driver_date_info_->Contains(gpu_info.driver_date, '-')) - return false; - } - if (gl_vendor_info_.get() != NULL && !gpu_info.gl_vendor.empty() && - !gl_vendor_info_->Contains(gpu_info.gl_vendor)) - return false; - if (gl_renderer_info_.get() != NULL && !gpu_info.gl_renderer.empty() && - !gl_renderer_info_->Contains(gpu_info.gl_renderer)) - return false; - if (gl_extensions_info_.get() != NULL && !gpu_info.gl_extensions.empty() && - !gl_extensions_info_->Contains(gpu_info.gl_extensions)) - return false; - if (perf_graphics_info_.get() != NULL && - (gpu_info.performance_stats.graphics == 0.0 || - !perf_graphics_info_->Contains(gpu_info.performance_stats.graphics))) - return false; - if (perf_gaming_info_.get() != NULL && - (gpu_info.performance_stats.gaming == 0.0 || - !perf_gaming_info_->Contains(gpu_info.performance_stats.gaming))) - return false; - if (perf_overall_info_.get() != NULL && - (gpu_info.performance_stats.overall == 0.0 || - !perf_overall_info_->Contains(gpu_info.performance_stats.overall))) - return false; - if (machine_model_info_.get() != NULL) { - std::vector<std::string> name_version; - base::SplitString(gpu_info.machine_model, ' ', &name_version); - if (name_version.size() == 2 && - !machine_model_info_->Contains(name_version[0], name_version[1])) - return false; - } - if (gpu_count_info_.get() != NULL && - !gpu_count_info_->Contains(gpu_info.secondary_gpus.size() + 1)) - return false; - if (cpu_brand_.get() != NULL) { - base::CPU cpu_info; - if (!cpu_brand_->Contains(cpu_info.cpu_brand())) - return false; - } - - for (size_t i = 0; i < exceptions_.size(); ++i) { - if (exceptions_[i]->Contains(os_type, os_version, gpu_info) && - !exceptions_[i]->NeedsMoreInfo(gpu_info)) - return false; - } - return true; -} - -bool GpuControlList::GpuControlListEntry::NeedsMoreInfo( - const GPUInfo& gpu_info) const { - // We only check for missing info that might be collected with a gl context. - // If certain info is missing due to some error, say, we fail to collect - // vendor_id/device_id, then even if we launch GPU process and create a gl - // context, we won't gather such missing info, so we still return false. - if (driver_vendor_info_.get() && gpu_info.driver_vendor.empty()) - return true; - if (driver_version_info_.get() && gpu_info.driver_version.empty()) - return true; - if (gl_vendor_info_.get() && gpu_info.gl_vendor.empty()) - return true; - if (gl_renderer_info_.get() && gpu_info.gl_renderer.empty()) - return true; - for (size_t i = 0; i < exceptions_.size(); ++i) { - if (exceptions_[i]->NeedsMoreInfo(gpu_info)) - return true; - } - return false; -} - -GpuControlList::OsType GpuControlList::GpuControlListEntry::GetOsType() const { - if (os_info_.get() == NULL) - return kOsAny; - return os_info_->type(); -} - -uint32 GpuControlList::GpuControlListEntry::id() const { - return id_; -} - -bool GpuControlList::GpuControlListEntry::disabled() const { - return disabled_; -} - -const std::set<int>& GpuControlList::GpuControlListEntry::features() const { - return features_; -} - -// static -bool GpuControlList::GpuControlListEntry::StringToFeature( - const std::string& feature_name, int* feature_id, - const FeatureMap& feature_map) { - FeatureMap::const_iterator iter = feature_map.find(feature_name); - if (iter != feature_map.end()) { - *feature_id = iter->second; - return true; - } - return false; -} - -GpuControlList::GpuControlList() - : max_entry_id_(0), - contains_unknown_fields_(false), - needs_more_info_(false), - supports_feature_type_all_(false) { -} - -GpuControlList::~GpuControlList() { - Clear(); -} - -bool GpuControlList::LoadList( - const std::string& json_context, GpuControlList::OsFilter os_filter) { - const std::string browser_version_string = "0"; - return LoadList(browser_version_string, json_context, os_filter); -} - -bool GpuControlList::LoadList( - const std::string& browser_version_string, - const std::string& json_context, - GpuControlList::OsFilter os_filter) { - std::vector<std::string> pieces; - if (!ProcessVersionString(browser_version_string, '.', &pieces)) - return false; - browser_version_ = browser_version_string; - - scoped_ptr<base::Value> root; - root.reset(base::JSONReader::Read(json_context)); - if (root.get() == NULL || !root->IsType(base::Value::TYPE_DICTIONARY)) - return false; - - base::DictionaryValue* root_dictionary = - static_cast<DictionaryValue*>(root.get()); - DCHECK(root_dictionary); - return LoadList(*root_dictionary, os_filter); -} - -bool GpuControlList::LoadList(const base::DictionaryValue& parsed_json, - GpuControlList::OsFilter os_filter) { - std::vector<ScopedGpuControlListEntry> entries; - - parsed_json.GetString("version", &version_); - std::vector<std::string> pieces; - if (!ProcessVersionString(version_, '.', &pieces)) - return false; - - const base::ListValue* list = NULL; - if (!parsed_json.GetList("entries", &list)) - return false; - - uint32 max_entry_id = 0; - bool contains_unknown_fields = false; - for (size_t i = 0; i < list->GetSize(); ++i) { - const base::DictionaryValue* list_item = NULL; - bool valid = list->GetDictionary(i, &list_item); - if (!valid || list_item == NULL) - return false; - // Check browser version compatibility: if the entry is not for the - // current browser version, don't process it. - BrowserVersionSupport browser_version_support = - IsEntrySupportedByCurrentBrowserVersion(list_item); - if (browser_version_support == kMalformed) - return false; - if (browser_version_support == kUnsupported) - continue; - DCHECK(browser_version_support == kSupported); - ScopedGpuControlListEntry entry(GpuControlListEntry::GetEntryFromValue( - list_item, true, feature_map_, supports_feature_type_all_)); - if (entry == NULL) - return false; - if (entry->id() > max_entry_id) - max_entry_id = entry->id(); - // If an unknown field is encountered, skip the entry; if an unknown - // feature is encountered, ignore the feature, but keep the entry. - if (entry->contains_unknown_fields()) { - contains_unknown_fields = true; - continue; - } - if (entry->contains_unknown_features()) - contains_unknown_fields = true; - entries.push_back(entry); - } - - Clear(); - OsType my_os = GetOsType(); - for (size_t i = 0; i < entries.size(); ++i) { - OsType entry_os = entries[i]->GetOsType(); - if (os_filter == GpuControlList::kAllOs || - entry_os == kOsAny || entry_os == my_os) - entries_.push_back(entries[i]); - } - max_entry_id_ = max_entry_id; - contains_unknown_fields_ = contains_unknown_fields; - return true; -} - -std::set<int> GpuControlList::MakeDecision( - GpuControlList::OsType os, - std::string os_version, - const GPUInfo& gpu_info) { - active_entries_.clear(); - std::set<int> features; - - needs_more_info_ = false; - std::set<int> possible_features; - - if (os == kOsAny) - os = GetOsType(); - if (os_version.empty()) { - os_version = base::SysInfo::OperatingSystemVersion(); - size_t pos = os_version.find_first_not_of("0123456789."); - if (pos != std::string::npos) - os_version = os_version.substr(0, pos); - } - std::vector<std::string> pieces; - if (!ProcessVersionString(os_version, '.', &pieces)) - os_version = "0"; - - for (size_t i = 0; i < entries_.size(); ++i) { - if (entries_[i]->Contains(os, os_version, gpu_info)) { - if (!entries_[i]->disabled()) { - MergeFeatureSets(&possible_features, entries_[i]->features()); - if (!entries_[i]->NeedsMoreInfo(gpu_info)) - MergeFeatureSets(&features, entries_[i]->features()); - } - active_entries_.push_back(entries_[i]); - } - } - - if (possible_features.size() > features.size()) - needs_more_info_ = true; - - return features; -} - -void GpuControlList::GetDecisionEntries( - std::vector<uint32>* entry_ids, bool disabled) const { - DCHECK(entry_ids); - entry_ids->clear(); - for (size_t i = 0; i < active_entries_.size(); ++i) { - if (disabled == active_entries_[i]->disabled()) - entry_ids->push_back(active_entries_[i]->id()); - } -} - -void GpuControlList::GetReasons(base::ListValue* problem_list) const { - DCHECK(problem_list); - for (size_t i = 0; i < active_entries_.size(); ++i) { - GpuControlListEntry* entry = active_entries_[i]; - if (entry->disabled()) - continue; - base::DictionaryValue* problem = new base::DictionaryValue(); - - problem->SetString("description", entry->description()); - - base::ListValue* cr_bugs = new base::ListValue(); - for (size_t j = 0; j < entry->cr_bugs().size(); ++j) - cr_bugs->Append(new base::FundamentalValue(entry->cr_bugs()[j])); - problem->Set("crBugs", cr_bugs); - - base::ListValue* webkit_bugs = new base::ListValue(); - for (size_t j = 0; j < entry->webkit_bugs().size(); ++j) { - webkit_bugs->Append(new base::FundamentalValue(entry->webkit_bugs()[j])); - } - problem->Set("webkitBugs", webkit_bugs); - - problem_list->Append(problem); - } -} - -size_t GpuControlList::num_entries() const { - return entries_.size(); -} - -uint32 GpuControlList::max_entry_id() const { - return max_entry_id_; -} - -std::string GpuControlList::version() const { - return version_; -} - -GpuControlList::OsType GpuControlList::GetOsType() { -#if defined(OS_CHROMEOS) - return kOsChromeOS; -#elif defined(OS_WIN) - return kOsWin; -#elif defined(OS_ANDROID) - return kOsAndroid; -#elif defined(OS_LINUX) || defined(OS_OPENBSD) - return kOsLinux; -#elif defined(OS_MACOSX) - return kOsMacosx; -#else - return kOsUnknown; -#endif -} - -void GpuControlList::Clear() { - entries_.clear(); - active_entries_.clear(); - max_entry_id_ = 0; - contains_unknown_fields_ = false; -} - -GpuControlList::BrowserVersionSupport -GpuControlList::IsEntrySupportedByCurrentBrowserVersion( - const base::DictionaryValue* value) { - DCHECK(value); - const base::DictionaryValue* browser_version_value = NULL; - if (value->GetDictionary("browser_version", &browser_version_value)) { - std::string version_op = "any"; - std::string version_string; - std::string version_string2; - browser_version_value->GetString(kOp, &version_op); - browser_version_value->GetString("number", &version_string); - browser_version_value->GetString("number2", &version_string2); - scoped_ptr<VersionInfo> browser_version_info; - browser_version_info.reset(new VersionInfo( - version_op, std::string(), version_string, version_string2)); - if (!browser_version_info->IsValid()) - return kMalformed; - if (browser_version_info->Contains(browser_version_)) - return kSupported; - return kUnsupported; - } - return kSupported; -} - -// static -GpuControlList::NumericOp GpuControlList::StringToNumericOp( - const std::string& op) { - if (op == "=") - return kEQ; - if (op == "<") - return kLT; - if (op == "<=") - return kLE; - if (op == ">") - return kGT; - if (op == ">=") - return kGE; - if (op == "any") - return kAny; - if (op == "between") - return kBetween; - return kUnknown; -} - -void GpuControlList::AddSupportedFeature( - const std::string& feature_name, int feature_id) { - feature_map_[feature_name] = feature_id; -} - -void GpuControlList::set_supports_feature_type_all(bool supported) { - supports_feature_type_all_ = supported; -} - -} // namespace content - diff --git a/content/browser/gpu/gpu_control_list.h b/content/browser/gpu/gpu_control_list.h deleted file mode 100644 index ab9ba58458..0000000000 --- a/content/browser/gpu/gpu_control_list.h +++ /dev/null @@ -1,498 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_BROWSER_GPU_GPU_CONTROL_LIST_H_ -#define CONTENT_BROWSER_GPU_GPU_CONTROL_LIST_H_ - -#include <set> -#include <string> -#include <vector> - -#include "base/basictypes.h" -#include "base/gtest_prod_util.h" -#include "base/hash_tables.h" -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" -#include "base/values.h" -#include "build/build_config.h" -#include "content/common/content_export.h" - -namespace content { -struct GPUInfo; - -class CONTENT_EXPORT GpuControlList { - public: - enum OsType { - kOsLinux, - kOsMacosx, - kOsWin, - kOsChromeOS, - kOsAndroid, - kOsAny, - kOsUnknown - }; - - enum OsFilter { - // In loading, ignore all entries that belong to other OS. - kCurrentOsOnly, - // In loading, keep all entries. This is for testing only. - kAllOs - }; - - GpuControlList(); - virtual ~GpuControlList(); - - // Loads control list information from a json file. - // If failed, the current GpuControlList is un-touched. - bool LoadList(const std::string& json_context, OsFilter os_filter); - bool LoadList(const std::string& browser_version_string, - const std::string& json_context, OsFilter os_filter); - - // Collects system information and combines them with gpu_info and control - // list information to decide which entries are applied to the current - // system and returns the union of features specified in each entry. - // If os is kOsAny, use the current OS; if os_version is empty, use the - // current OS version. - std::set<int> MakeDecision( - OsType os, std::string os_version, const GPUInfo& gpu_info); - - // Collects the active entries from the last MakeDecision() call. - // If disabled set to true, return entries that are disabled; otherwise, - // return enabled entries. - void GetDecisionEntries(std::vector<uint32>* entry_ids, - bool disabled) const; - - // Returns the description and bugs from active entries from the last - // MakeDecision() call. - // - // Each problems has: - // { - // "description": "Your GPU is too old", - // "crBugs": [1234], - // "webkitBugs": [] - // } - void GetReasons(base::ListValue* problem_list) const; - - // Return the largest entry id. This is used for histogramming. - uint32 max_entry_id() const; - - // Returns the version of the control list. - std::string version() const; - - // Check if we need more gpu info to make the decisions. - // This is computed from the last MakeDecision() call. - // If yes, we should create a gl context and do a full gpu info collection. - bool needs_more_info() const { return needs_more_info_; } - - // Check if any entries contain unknown fields. This is only for tests. - bool contains_unknown_fields() const { return contains_unknown_fields_; } - - // Returns the number of entries. This is only for tests. - size_t num_entries() const; - - // Register a feature to FeatureMap - used to construct a GpuControlList. - void AddSupportedFeature(const std::string& feature_name, int feature_id); - // Register whether "all" is recognized as all features. - void set_supports_feature_type_all(bool supported); - - private: - friend class GpuControlListEntryTest; - friend class MachineModelInfoTest; - friend class NumberInfoTest; - friend class OsInfoTest; - friend class StringInfoTest; - friend class VersionInfoTest; - - enum BrowserVersionSupport { - kSupported, - kUnsupported, - kMalformed - }; - - enum NumericOp { - kBetween, // <= * <= - kEQ, // = - kLT, // < - kLE, // <= - kGT, // > - kGE, // >= - kAny, - kUnknown // Indicates the data is invalid. - }; - - class CONTENT_EXPORT VersionInfo { - public: - // If version_style is empty, it defaults to kNumerical. - VersionInfo(const std::string& version_op, - const std::string& version_style, - const std::string& version_string, - const std::string& version_string2); - ~VersionInfo(); - - // Determines if a given version is included in the VersionInfo range. - // "splitter" divides version string into segments. - bool Contains(const std::string& version, char splitter) const; - // Same as above, using '.' as splitter. - bool Contains(const std::string& version) const; - - // Determine if the version_style is lexical. - bool IsLexical() const; - - // Determines if the VersionInfo contains valid information. - bool IsValid() const; - - private: - enum VersionStyle { - kVersionStyleNumerical, - kVersionStyleLexical, - kVersionStyleUnknown - }; - - static VersionStyle StringToVersionStyle(const std::string& version_style); - - // Compare two version strings. - // Return 1 if version > version_ref, - // 0 if version = version_ref, - // -1 if version < version_ref. - // Note that we only compare as many segments as both versions contain. - // For example: Compare("10.3.1", "10.3") returns 0, - // Compare("10.3", "10.3.1") returns 0. - // If "version_style" is Lexical, the first segment is compared - // numerically, all other segments are compared lexically. - // Lexical is used for AMD Linux driver versions only. - static int Compare(const std::vector<std::string>& version, - const std::vector<std::string>& version_ref, - VersionStyle version_style); - - NumericOp op_; - VersionStyle version_style_; - std::vector<std::string> version_; - std::vector<std::string> version2_; - }; - - class CONTENT_EXPORT OsInfo { - public: - OsInfo(const std::string& os, - const std::string& version_op, - const std::string& version_string, - const std::string& version_string2); - ~OsInfo(); - - // Determines if a given os/version is included in the OsInfo set. - bool Contains(OsType type, const std::string& version) const; - - // Determines if the VersionInfo contains valid information. - bool IsValid() const; - - OsType type() const; - - // Maps string to OsType; returns kOsUnknown if it's not a valid os. - static OsType StringToOsType(const std::string& os); - - private: - OsType type_; - scoped_ptr<VersionInfo> version_info_; - }; - - class CONTENT_EXPORT StringInfo { - public: - StringInfo(const std::string& string_op, const std::string& string_value); - - // Determines if a given string is included in the StringInfo. - bool Contains(const std::string& value) const; - - // Determines if the StringInfo contains valid information. - bool IsValid() const; - - private: - enum Op { - kContains, - kBeginWith, - kEndWith, - kEQ, // = - kUnknown // Indicates StringInfo data is invalid. - }; - - // Maps string to Op; returns kUnknown if it's not a valid Op. - static Op StringToOp(const std::string& string_op); - - Op op_; - std::string value_; - }; - - class CONTENT_EXPORT FloatInfo { - public: - FloatInfo(const std::string& float_op, - const std::string& float_value, - const std::string& float_value2); - - // Determines if a given float is included in the FloatInfo. - bool Contains(float value) const; - - // Determines if the FloatInfo contains valid information. - bool IsValid() const; - - private: - NumericOp op_; - float value_; - float value2_; - }; - - class CONTENT_EXPORT IntInfo { - public: - IntInfo(const std::string& int_op, - const std::string& int_value, - const std::string& int_value2); - - // Determines if a given int is included in the IntInfo. - bool Contains(int value) const; - - // Determines if the IntInfo contains valid information. - bool IsValid() const; - - private: - NumericOp op_; - int value_; - int value2_; - }; - - class CONTENT_EXPORT MachineModelInfo { - public: - MachineModelInfo(const std::string& name_op, - const std::string& name_value, - const std::string& version_op, - const std::string& version_string, - const std::string& version_string2); - ~MachineModelInfo(); - - // Determines if a given name/version is included in the MachineModelInfo. - bool Contains(const std::string& name, const std::string& version) const; - - // Determines if the MachineModelInfo contains valid information. - bool IsValid() const; - - private: - scoped_ptr<StringInfo> name_info_; - scoped_ptr<VersionInfo> version_info_; - }; - - class GpuControlListEntry; - typedef scoped_refptr<GpuControlListEntry> ScopedGpuControlListEntry; - - typedef base::hash_map<std::string, int> FeatureMap; - - class CONTENT_EXPORT GpuControlListEntry - : public base::RefCounted<GpuControlListEntry> { - public: - // Constructs GpuControlListEntry from DictionaryValue loaded from json. - // Top-level entry must have an id number. Others are exceptions. - static ScopedGpuControlListEntry GetEntryFromValue( - const base::DictionaryValue* value, bool top_level, - const FeatureMap& feature_map, - bool supports_feature_type_all); - - // Determines if a given os/gc/machine_model/driver is included in the - // Entry set. - bool Contains(OsType os_type, const std::string& os_version, - const GPUInfo& gpu_info) const; - - // Determines whether we needs more gpu info to make the blacklisting - // decision. It should only be checked if Contains() returns true. - bool NeedsMoreInfo(const GPUInfo& gpu_info) const; - - // Returns the OsType. - OsType GetOsType() const; - - // Returns the entry's unique id. 0 is reserved. - uint32 id() const; - - // Returns whether the entry is disabled. - bool disabled() const; - - // Returns the description of the entry - const std::string& description() const { return description_; } - - // Returns a list of Chromium and Webkit bugs applicable to this entry - const std::vector<int>& cr_bugs() const { return cr_bugs_; } - const std::vector<int>& webkit_bugs() const { return webkit_bugs_; } - - // Returns the blacklisted features in this entry. - const std::set<int>& features() const; - - // Returns true if an unknown field is encountered. - bool contains_unknown_fields() const { - return contains_unknown_fields_; - } - // Returns true if an unknown blacklist feature is encountered. - bool contains_unknown_features() const { - return contains_unknown_features_; - } - - private: - friend class base::RefCounted<GpuControlListEntry>; - - enum MultiGpuStyle { - kMultiGpuStyleOptimus, - kMultiGpuStyleAMDSwitchable, - kMultiGpuStyleNone - }; - - enum MultiGpuCategory { - kMultiGpuCategoryPrimary, - kMultiGpuCategorySecondary, - kMultiGpuCategoryAny, - kMultiGpuCategoryNone - }; - - GpuControlListEntry(); - ~GpuControlListEntry(); - - bool SetId(uint32 id); - - void SetDisabled(bool disabled); - - bool SetOsInfo(const std::string& os, - const std::string& version_op, - const std::string& version_string, - const std::string& version_string2); - - bool SetVendorId(const std::string& vendor_id_string); - - bool AddDeviceId(const std::string& device_id_string); - - bool SetMultiGpuStyle(const std::string& multi_gpu_style_string); - - bool SetMultiGpuCategory(const std::string& multi_gpu_category_string); - - bool SetDriverVendorInfo(const std::string& vendor_op, - const std::string& vendor_value); - - bool SetDriverVersionInfo(const std::string& version_op, - const std::string& version_style, - const std::string& version_string, - const std::string& version_string2); - - bool SetDriverDateInfo(const std::string& date_op, - const std::string& date_string, - const std::string& date_string2); - - bool SetGLVendorInfo(const std::string& vendor_op, - const std::string& vendor_value); - - bool SetGLRendererInfo(const std::string& renderer_op, - const std::string& renderer_value); - - bool SetGLExtensionsInfo(const std::string& extensions_op, - const std::string& extensions_value); - - bool SetCpuBrand(const std::string& cpu_op, - const std::string& cpu_value); - - bool SetPerfGraphicsInfo(const std::string& op, - const std::string& float_string, - const std::string& float_string2); - - bool SetPerfGamingInfo(const std::string& op, - const std::string& float_string, - const std::string& float_string2); - - bool SetPerfOverallInfo(const std::string& op, - const std::string& float_string, - const std::string& float_string2); - - bool SetMachineModelInfo(const std::string& name_op, - const std::string& name_value, - const std::string& version_op, - const std::string& version_string, - const std::string& version_string2); - - bool SetGpuCountInfo(const std::string& op, - const std::string& int_string, - const std::string& int_string2); - - bool SetFeatures(const std::vector<std::string>& features, - const FeatureMap& feature_map, - bool supports_feature_type_all); - - void AddException(ScopedGpuControlListEntry exception); - - static MultiGpuStyle StringToMultiGpuStyle(const std::string& style); - - static MultiGpuCategory StringToMultiGpuCategory( - const std::string& category); - - // map a feature_name to feature_id. If the string is not a registered - // feature name, return false. - static bool StringToFeature(const std::string& feature_name, - int* feature_id, - const FeatureMap& feature_map); - - uint32 id_; - bool disabled_; - std::string description_; - std::vector<int> cr_bugs_; - std::vector<int> webkit_bugs_; - scoped_ptr<OsInfo> os_info_; - uint32 vendor_id_; - std::vector<uint32> device_id_list_; - MultiGpuStyle multi_gpu_style_; - MultiGpuCategory multi_gpu_category_; - scoped_ptr<StringInfo> driver_vendor_info_; - scoped_ptr<VersionInfo> driver_version_info_; - scoped_ptr<VersionInfo> driver_date_info_; - scoped_ptr<StringInfo> gl_vendor_info_; - scoped_ptr<StringInfo> gl_renderer_info_; - scoped_ptr<StringInfo> gl_extensions_info_; - scoped_ptr<StringInfo> cpu_brand_; - scoped_ptr<FloatInfo> perf_graphics_info_; - scoped_ptr<FloatInfo> perf_gaming_info_; - scoped_ptr<FloatInfo> perf_overall_info_; - scoped_ptr<MachineModelInfo> machine_model_info_; - scoped_ptr<IntInfo> gpu_count_info_; - std::set<int> features_; - std::vector<ScopedGpuControlListEntry> exceptions_; - bool contains_unknown_fields_; - bool contains_unknown_features_; - }; - - // Gets the current OS type. - static OsType GetOsType(); - - bool LoadList(const base::DictionaryValue& parsed_json, OsFilter os_filter); - - void Clear(); - - // Check if the entry is supported by the current version of browser. - // By default, if there is no browser version information in the entry, - // return kSupported; - BrowserVersionSupport IsEntrySupportedByCurrentBrowserVersion( - const base::DictionaryValue* value); - - static NumericOp StringToNumericOp(const std::string& op); - - std::string version_; - std::vector<ScopedGpuControlListEntry> entries_; - - std::string browser_version_; - - // This records all the blacklist entries that are appliable to the current - // user machine. It is updated everytime MakeDecision() is called and is - // used later by GetDecisionEntries(). - std::vector<ScopedGpuControlListEntry> active_entries_; - - uint32 max_entry_id_; - - bool contains_unknown_fields_; - - bool needs_more_info_; - - // The features a GpuControlList recognizes and handles. - FeatureMap feature_map_; - bool supports_feature_type_all_; -}; - -} // namespace content - -#endif // CONTENT_BROWSER_GPU_GPU_CONTROL_LIST_H_ - diff --git a/content/browser/gpu/gpu_control_list_entry_unittest.cc b/content/browser/gpu/gpu_control_list_entry_unittest.cc deleted file mode 100644 index 16b2eb33a7..0000000000 --- a/content/browser/gpu/gpu_control_list_entry_unittest.cc +++ /dev/null @@ -1,748 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/json/json_reader.h" -#include "content/browser/gpu/gpu_control_list.h" -#include "content/public/common/gpu_info.h" -#include "testing/gtest/include/gtest/gtest.h" - -#define LONG_STRING_CONST(...) #__VA_ARGS__ - -namespace content { - -enum TestFeatureType { - TEST_FEATURE_0 = 0, - TEST_FEATURE_1, - TEST_FEATURE_2 -}; - -class GpuControlListEntryTest : public testing::Test { - public: - GpuControlListEntryTest() { } - virtual ~GpuControlListEntryTest() { } - - const GPUInfo& gpu_info() const { - return gpu_info_; - } - - typedef GpuControlList::ScopedGpuControlListEntry ScopedEntry; - - static ScopedEntry GetEntryFromString( - const std::string& json, bool supports_feature_type_all) { - scoped_ptr<base::Value> root; - root.reset(base::JSONReader::Read(json)); - DictionaryValue* value = NULL; - if (root.get() == NULL || !root->GetAsDictionary(&value)) - return NULL; - - GpuControlList::FeatureMap feature_map; - feature_map["test_feature_0"] = TEST_FEATURE_0; - feature_map["test_feature_1"] = TEST_FEATURE_1; - feature_map["test_feature_2"] = TEST_FEATURE_2; - - return GpuControlList::GpuControlListEntry::GetEntryFromValue( - value, true, feature_map, supports_feature_type_all); - } - - static ScopedEntry GetEntryFromString(const std::string& json) { - return GetEntryFromString(json, false); - } - - virtual void SetUp() { - gpu_info_.gpu.vendor_id = 0x10de; - gpu_info_.gpu.device_id = 0x0640; - gpu_info_.driver_vendor = "NVIDIA"; - gpu_info_.driver_version = "1.6.18"; - gpu_info_.driver_date = "7-14-2009"; - gpu_info_.machine_model = "MacBookPro 7.1"; - gpu_info_.gl_vendor = "NVIDIA Corporation"; - gpu_info_.gl_renderer = "NVIDIA GeForce GT 120 OpenGL Engine"; - gpu_info_.performance_stats.graphics = 5.0; - gpu_info_.performance_stats.gaming = 5.0; - gpu_info_.performance_stats.overall = 5.0; - } - - private: - GPUInfo gpu_info_; -}; - -TEST_F(GpuControlListEntryTest, DetailedEntry) { - const std::string json = LONG_STRING_CONST( - { - "id": 5, - "description": "test entry", - "cr_bugs": [1024, 678], - "webkit_bugs": [1950], - "os": { - "type": "macosx", - "version": { - "op": "=", - "number": "10.6.4" - } - }, - "vendor_id": "0x10de", - "device_id": ["0x0640"], - "driver_version": { - "op": "=", - "number": "1.6.18" - }, - "features": [ - "test_feature_0" - ] - } - ); - - ScopedEntry entry(GetEntryFromString(json)); - EXPECT_TRUE(entry != NULL); - EXPECT_EQ(GpuControlList::kOsMacosx, entry->GetOsType()); - EXPECT_FALSE(entry->disabled()); - EXPECT_EQ(5u, entry->id()); - EXPECT_STREQ("test entry", entry->description().c_str()); - EXPECT_EQ(2u, entry->cr_bugs().size()); - EXPECT_EQ(1024, entry->cr_bugs()[0]); - EXPECT_EQ(678, entry->cr_bugs()[1]); - EXPECT_EQ(1u, entry->webkit_bugs().size()); - EXPECT_EQ(1950, entry->webkit_bugs()[0]); - EXPECT_EQ(1u, entry->features().size()); - EXPECT_EQ(1u, entry->features().count(TEST_FEATURE_0)); - EXPECT_FALSE(entry->contains_unknown_fields()); - EXPECT_FALSE(entry->contains_unknown_features()); - EXPECT_FALSE(entry->NeedsMoreInfo(gpu_info())); - EXPECT_TRUE(entry->Contains( - GpuControlList::kOsMacosx, "10.6.4", gpu_info())); -} - -TEST_F(GpuControlListEntryTest, VendorOnAllOsEntry) { - const std::string json = LONG_STRING_CONST( - { - "id": 1, - "vendor_id": "0x10de", - "features": [ - "test_feature_0" - ] - } - ); - ScopedEntry entry(GetEntryFromString(json)); - EXPECT_TRUE(entry != NULL); - EXPECT_EQ(GpuControlList::kOsAny, entry->GetOsType()); - - const GpuControlList::OsType os_type[] = { - GpuControlList::kOsMacosx, - GpuControlList::kOsWin, - GpuControlList::kOsLinux, - GpuControlList::kOsChromeOS, - GpuControlList::kOsAndroid - }; - for (size_t i = 0; i < arraysize(os_type); ++i) - EXPECT_TRUE(entry->Contains(os_type[i], "10.6", gpu_info())); -} - -TEST_F(GpuControlListEntryTest, VendorOnLinuxEntry) { - const std::string json = LONG_STRING_CONST( - { - "id": 1, - "os": { - "type": "linux" - }, - "vendor_id": "0x10de", - "features": [ - "test_feature_0" - ] - } - ); - ScopedEntry entry(GetEntryFromString(json)); - EXPECT_TRUE(entry != NULL); - EXPECT_EQ(GpuControlList::kOsLinux, entry->GetOsType()); - - const GpuControlList::OsType os_type[] = { - GpuControlList::kOsMacosx, - GpuControlList::kOsWin, - GpuControlList::kOsChromeOS, - GpuControlList::kOsAndroid - }; - for (size_t i = 0; i < arraysize(os_type); ++i) - EXPECT_FALSE(entry->Contains(os_type[i], "10.6", gpu_info())); - EXPECT_TRUE(entry->Contains( - GpuControlList::kOsLinux, "10.6", gpu_info())); -} - -TEST_F(GpuControlListEntryTest, AllExceptNVidiaOnLinuxEntry) { - const std::string json = LONG_STRING_CONST( - { - "id": 1, - "os": { - "type": "linux" - }, - "exceptions": [ - { - "vendor_id": "0x10de" - } - ], - "features": [ - "test_feature_0" - ] - } - ); - ScopedEntry entry(GetEntryFromString(json)); - EXPECT_TRUE(entry != NULL); - EXPECT_EQ(GpuControlList::kOsLinux, entry->GetOsType()); - - const GpuControlList::OsType os_type[] = { - GpuControlList::kOsMacosx, - GpuControlList::kOsWin, - GpuControlList::kOsLinux, - GpuControlList::kOsChromeOS, - GpuControlList::kOsAndroid - }; - for (size_t i = 0; i < arraysize(os_type); ++i) - EXPECT_FALSE(entry->Contains(os_type[i], "10.6", gpu_info())); -} - -TEST_F(GpuControlListEntryTest, AllExceptIntelOnLinuxEntry) { - const std::string json = LONG_STRING_CONST( - { - "id": 1, - "os": { - "type": "linux" - }, - "exceptions": [ - { - "vendor_id": "0x8086" - } - ], - "features": [ - "test_feature_0" - ] - } - ); - ScopedEntry entry(GetEntryFromString(json)); - EXPECT_TRUE(entry != NULL); - EXPECT_EQ(GpuControlList::kOsLinux, entry->GetOsType()); - - const GpuControlList::OsType os_type[] = { - GpuControlList::kOsMacosx, - GpuControlList::kOsWin, - GpuControlList::kOsChromeOS, - GpuControlList::kOsAndroid - }; - for (size_t i = 0; i < arraysize(os_type); ++i) - EXPECT_FALSE(entry->Contains(os_type[i], "10.6", gpu_info())); - EXPECT_TRUE(entry->Contains( - GpuControlList::kOsLinux, "10.6", gpu_info())); -} - -TEST_F(GpuControlListEntryTest, DateOnWindowsEntry) { - const std::string json = LONG_STRING_CONST( - { - "id": 1, - "os": { - "type": "win" - }, - "driver_date": { - "op": "<", - "number": "2010.5.8" - }, - "features": [ - "test_feature_0" - ] - } - ); - ScopedEntry entry(GetEntryFromString(json)); - EXPECT_TRUE(entry != NULL); - EXPECT_EQ(GpuControlList::kOsWin, entry->GetOsType()); - - GPUInfo gpu_info; - gpu_info.driver_date = "4-12-2010"; - EXPECT_TRUE(entry->Contains( - GpuControlList::kOsWin, "10.6", gpu_info)); - gpu_info.driver_date = "5-8-2010"; - EXPECT_FALSE(entry->Contains( - GpuControlList::kOsWin, "10.6", gpu_info)); - gpu_info.driver_date = "5-9-2010"; - EXPECT_FALSE(entry->Contains( - GpuControlList::kOsWin, "10.6", gpu_info)); -} - -TEST_F(GpuControlListEntryTest, MultipleDevicesEntry) { - const std::string json = LONG_STRING_CONST( - { - "id": 1, - "vendor_id": "0x10de", - "device_id": ["0x1023", "0x0640"], - "features": [ - "test_feature_0" - ] - } - ); - ScopedEntry entry(GetEntryFromString(json)); - EXPECT_TRUE(entry != NULL); - EXPECT_EQ(GpuControlList::kOsAny, entry->GetOsType()); - - const GpuControlList::OsType os_type[] = { - GpuControlList::kOsMacosx, - GpuControlList::kOsWin, - GpuControlList::kOsLinux, - GpuControlList::kOsChromeOS, - GpuControlList::kOsAndroid - }; - for (size_t i = 0; i < arraysize(os_type); ++i) - EXPECT_TRUE(entry->Contains(os_type[i], "10.6", gpu_info())); -} - -TEST_F(GpuControlListEntryTest, ChromeOSEntry) { - const std::string json = LONG_STRING_CONST( - { - "id": 1, - "os": { - "type": "chromeos" - }, - "features": [ - "test_feature_0" - ] - } - ); - ScopedEntry entry(GetEntryFromString(json)); - EXPECT_TRUE(entry != NULL); - EXPECT_EQ(GpuControlList::kOsChromeOS, entry->GetOsType()); - - const GpuControlList::OsType os_type[] = { - GpuControlList::kOsMacosx, - GpuControlList::kOsWin, - GpuControlList::kOsLinux, - GpuControlList::kOsAndroid - }; - for (size_t i = 0; i < arraysize(os_type); ++i) - EXPECT_FALSE(entry->Contains(os_type[i], "10.6", gpu_info())); - EXPECT_TRUE(entry->Contains( - GpuControlList::kOsChromeOS, "10.6", gpu_info())); -} - -TEST_F(GpuControlListEntryTest, MalformedVendor) { - const std::string json = LONG_STRING_CONST( - { - "id": 1, - "vendor_id": "[0x10de]", - "features": [ - "test_feature_0" - ] - } - ); - ScopedEntry entry(GetEntryFromString(json)); - EXPECT_TRUE(entry == NULL); -} - -TEST_F(GpuControlListEntryTest, UnknownFieldEntry) { - const std::string json = LONG_STRING_CONST( - { - "id": 1, - "unknown_field": 0, - "features": [ - "test_feature_0" - ] - } - ); - ScopedEntry entry(GetEntryFromString(json)); - EXPECT_TRUE(entry != NULL); - EXPECT_TRUE(entry->contains_unknown_fields()); - EXPECT_FALSE(entry->contains_unknown_features()); -} - -TEST_F(GpuControlListEntryTest, UnknownExceptionFieldEntry) { - const std::string json = LONG_STRING_CONST( - { - "id": 2, - "exceptions": [ - { - "unknown_field": 0 - } - ], - "features": [ - "test_feature_0" - ] - } - ); - ScopedEntry entry(GetEntryFromString(json)); - EXPECT_TRUE(entry != NULL); - EXPECT_TRUE(entry->contains_unknown_fields()); - EXPECT_FALSE(entry->contains_unknown_features()); -} - -TEST_F(GpuControlListEntryTest, UnknownFeatureEntry) { - const std::string json = LONG_STRING_CONST( - { - "id": 1, - "features": [ - "some_unknown_feature", - "test_feature_0" - ] - } - ); - ScopedEntry entry(GetEntryFromString(json)); - EXPECT_TRUE(entry != NULL); - EXPECT_FALSE(entry->contains_unknown_fields()); - EXPECT_TRUE(entry->contains_unknown_features()); - EXPECT_EQ(1u, entry->features().size()); - EXPECT_EQ(1u, entry->features().count(TEST_FEATURE_0)); - - const GpuControlList::OsType os_type[] = { - GpuControlList::kOsMacosx, - GpuControlList::kOsWin, - GpuControlList::kOsLinux, - GpuControlList::kOsChromeOS, - GpuControlList::kOsAndroid - }; - for (size_t i = 0; i < arraysize(os_type); ++i) - EXPECT_TRUE(entry->Contains(os_type[i], "10.6", gpu_info())); -} - -TEST_F(GpuControlListEntryTest, GlVendorEntry) { - const std::string json = LONG_STRING_CONST( - { - "id": 1, - "gl_vendor": { - "op": "beginwith", - "value": "NVIDIA" - }, - "features": [ - "test_feature_0" - ] - } - ); - ScopedEntry entry(GetEntryFromString(json)); - EXPECT_TRUE(entry != NULL); - - const GpuControlList::OsType os_type[] = { - GpuControlList::kOsMacosx, - GpuControlList::kOsWin, - GpuControlList::kOsLinux, - GpuControlList::kOsChromeOS, - GpuControlList::kOsAndroid - }; - for (size_t i = 0; i < arraysize(os_type); ++i) - EXPECT_TRUE(entry->Contains(os_type[i], "10.6", gpu_info())); -} - -TEST_F(GpuControlListEntryTest, GlRendererEntry) { - const std::string json = LONG_STRING_CONST( - { - "id": 1, - "gl_renderer": { - "op": "contains", - "value": "GeForce" - }, - "features": [ - "test_feature_0" - ] - } - ); - ScopedEntry entry(GetEntryFromString(json)); - EXPECT_TRUE(entry != NULL); - - const GpuControlList::OsType os_type[] = { - GpuControlList::kOsMacosx, - GpuControlList::kOsWin, - GpuControlList::kOsLinux, - GpuControlList::kOsChromeOS, - GpuControlList::kOsAndroid - }; - for (size_t i = 0; i < arraysize(os_type); ++i) - EXPECT_TRUE(entry->Contains(os_type[i], "10.6", gpu_info())); -} - -TEST_F(GpuControlListEntryTest, PerfGraphicsEntry) { - const std::string json = LONG_STRING_CONST( - { - "id": 1, - "perf_graphics": { - "op": "<", - "value": "6.0" - }, - "features": [ - "test_feature_0" - ] - } - ); - ScopedEntry entry(GetEntryFromString(json)); - EXPECT_TRUE(entry != NULL); - EXPECT_TRUE(entry->Contains( - GpuControlList::kOsWin, "10.6", gpu_info())); -} - -TEST_F(GpuControlListEntryTest, PerfGamingEntry) { - const std::string json = LONG_STRING_CONST( - { - "id": 1, - "perf_graphics": { - "op": "<=", - "value": "4.0" - }, - "features": [ - "test_feature_0" - ] - } - ); - ScopedEntry entry(GetEntryFromString(json)); - EXPECT_TRUE(entry != NULL); - EXPECT_FALSE(entry->Contains( - GpuControlList::kOsWin, "10.6", gpu_info())); -} - -TEST_F(GpuControlListEntryTest, PerfOverallEntry) { - const std::string json = LONG_STRING_CONST( - { - "id": 1, - "perf_overall": { - "op": "between", - "value": "1.0", - "value2": "9.0" - }, - "features": [ - "test_feature_0" - ] - } - ); - ScopedEntry entry(GetEntryFromString(json)); - EXPECT_TRUE(entry != NULL); - EXPECT_TRUE(entry->Contains( - GpuControlList::kOsWin, "10.6", gpu_info())); -} - -TEST_F(GpuControlListEntryTest, DisabledEntry) { - const std::string json = LONG_STRING_CONST( - { - "id": 1, - "disabled": true, - "features": [ - "test_feature_0" - ] - } - ); - ScopedEntry entry(GetEntryFromString(json)); - EXPECT_TRUE(entry != NULL); - EXPECT_TRUE(entry->disabled()); -} - -TEST_F(GpuControlListEntryTest, OptimusEntry) { - const std::string json = LONG_STRING_CONST( - { - "id": 1, - "os": { - "type": "linux" - }, - "multi_gpu_style": "optimus", - "features": [ - "test_feature_0" - ] - } - ); - GPUInfo gpu_info; - gpu_info.optimus = true; - - ScopedEntry entry(GetEntryFromString(json)); - EXPECT_TRUE(entry != NULL); - EXPECT_EQ(GpuControlList::kOsLinux, entry->GetOsType()); - EXPECT_TRUE(entry->Contains( - GpuControlList::kOsLinux, "10.6", gpu_info)); -} - -TEST_F(GpuControlListEntryTest, AMDSwitchableEntry) { - const std::string json = LONG_STRING_CONST( - { - "id": 1, - "os": { - "type": "macosx" - }, - "multi_gpu_style": "amd_switchable", - "features": [ - "test_feature_0" - ] - } - ); - GPUInfo gpu_info; - gpu_info.amd_switchable = true; - - ScopedEntry entry(GetEntryFromString(json)); - EXPECT_TRUE(entry != NULL); - EXPECT_EQ(GpuControlList::kOsMacosx, entry->GetOsType()); - EXPECT_TRUE(entry->Contains( - GpuControlList::kOsMacosx, "10.6", gpu_info)); -} - -TEST_F(GpuControlListEntryTest, LexicalDriverVersionEntry) { - const std::string json = LONG_STRING_CONST( - { - "id": 1, - "os": { - "type": "linux" - }, - "vendor_id": "0x1002", - "driver_version": { - "op": "=", - "style": "lexical", - "number": "8.76" - }, - "features": [ - "test_feature_0" - ] - } - ); - GPUInfo gpu_info; - gpu_info.gpu.vendor_id = 0x1002; - - ScopedEntry entry(GetEntryFromString(json)); - EXPECT_TRUE(entry != NULL); - EXPECT_EQ(GpuControlList::kOsLinux, entry->GetOsType()); - - gpu_info.driver_version = "8.76"; - EXPECT_TRUE(entry->Contains( - GpuControlList::kOsLinux, "10.6", gpu_info)); - - gpu_info.driver_version = "8.768"; - EXPECT_TRUE(entry->Contains( - GpuControlList::kOsLinux, "10.6", gpu_info)); - - gpu_info.driver_version = "8.76.8"; - EXPECT_TRUE(entry->Contains( - GpuControlList::kOsLinux, "10.6", gpu_info)); -} - -TEST_F(GpuControlListEntryTest, MultipleGPUsAnyEntry) { - const std::string json = LONG_STRING_CONST( - { - "id": 1, - "os": { - "type": "macosx" - }, - "vendor_id": "0x8086", - "device_id": ["0x0166"], - "multi_gpu_category": "any", - "features": [ - "test_feature_0" - ] - } - ); - ScopedEntry entry(GetEntryFromString(json)); - EXPECT_TRUE(entry != NULL); - EXPECT_EQ(GpuControlList::kOsMacosx, entry->GetOsType()); - - GPUInfo gpu_info; - gpu_info.gpu.vendor_id = 0x10de; - gpu_info.gpu.device_id = 0x1976; - EXPECT_FALSE(entry->Contains( - GpuControlList::kOsMacosx, "10.6", gpu_info)); - - GPUInfo::GPUDevice gpu_device; - gpu_device.vendor_id = 0x8086; - gpu_device.device_id = 0x0166; - gpu_info.secondary_gpus.push_back(gpu_device); - EXPECT_TRUE(entry->Contains( - GpuControlList::kOsMacosx, "10.6", gpu_info)); -} - -TEST_F(GpuControlListEntryTest, MultipleGPUsSecondaryEntry) { - const std::string json = LONG_STRING_CONST( - { - "id": 1, - "os": { - "type": "macosx" - }, - "vendor_id": "0x8086", - "device_id": ["0x0166"], - "multi_gpu_category": "secondary", - "features": [ - "test_feature_0" - ] - } - ); - ScopedEntry entry(GetEntryFromString(json)); - EXPECT_TRUE(entry != NULL); - EXPECT_EQ(GpuControlList::kOsMacosx, entry->GetOsType()); - - GPUInfo gpu_info; - gpu_info.gpu.vendor_id = 0x10de; - gpu_info.gpu.device_id = 0x1976; - EXPECT_FALSE(entry->Contains( - GpuControlList::kOsMacosx, "10.6", gpu_info)); - - GPUInfo::GPUDevice gpu_device; - gpu_device.vendor_id = 0x8086; - gpu_device.device_id = 0x0166; - gpu_info.secondary_gpus.push_back(gpu_device); - EXPECT_TRUE(entry->Contains( - GpuControlList::kOsMacosx, "10.6", gpu_info)); -} - -TEST_F(GpuControlListEntryTest, NeedsMoreInfoEntry) { - const std::string json = LONG_STRING_CONST( - { - "id": 1, - "vendor_id": "0x8086", - "driver_version": { - "op": "<", - "number": "10.7" - }, - "features": [ - "test_feature_1" - ] - } - ); - ScopedEntry entry(GetEntryFromString(json)); - EXPECT_TRUE(entry != NULL); - - GPUInfo gpu_info; - gpu_info.gpu.vendor_id = 0x8086; - EXPECT_TRUE(entry->NeedsMoreInfo(gpu_info)); - - gpu_info.driver_version = "10.6"; - EXPECT_FALSE(entry->NeedsMoreInfo(gpu_info)); -} - -TEST_F(GpuControlListEntryTest, NeedsMoreInfoForExceptionsEntry) { - const std::string json = LONG_STRING_CONST( - { - "id": 1, - "vendor_id": "0x8086", - "exceptions": [ - { - "gl_renderer": { - "op": "contains", - "value": "mesa" - } - } - ], - "features": [ - "test_feature_1" - ] - } - ); - ScopedEntry entry(GetEntryFromString(json)); - EXPECT_TRUE(entry != NULL); - - GPUInfo gpu_info; - gpu_info.gpu.vendor_id = 0x8086; - EXPECT_TRUE(entry->NeedsMoreInfo(gpu_info)); - - gpu_info.gl_renderer = "mesa"; - EXPECT_FALSE(entry->NeedsMoreInfo(gpu_info)); -} - -TEST_F(GpuControlListEntryTest, FeatureTypeAllEntry) { - const std::string json = LONG_STRING_CONST( - { - "id": 1, - "features": [ - "all" - ] - } - ); - ScopedEntry entry(GetEntryFromString(json, true)); - EXPECT_TRUE(entry != NULL); - EXPECT_EQ(3u, entry->features().size()); - EXPECT_EQ(1u, entry->features().count(TEST_FEATURE_0)); - EXPECT_EQ(1u, entry->features().count(TEST_FEATURE_1)); - EXPECT_EQ(1u, entry->features().count(TEST_FEATURE_2)); -} - -} // namespace content - diff --git a/content/browser/gpu/gpu_control_list_machine_model_info_unittest.cc b/content/browser/gpu/gpu_control_list_machine_model_info_unittest.cc deleted file mode 100644 index 8d00a33573..0000000000 --- a/content/browser/gpu/gpu_control_list_machine_model_info_unittest.cc +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/browser/gpu/gpu_control_list.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace content { - -class MachineModelInfoTest : public testing::Test { - public: - MachineModelInfoTest() { } - virtual ~MachineModelInfoTest() { } - - typedef GpuControlList::MachineModelInfo MachineModelInfo; -}; - -TEST_F(MachineModelInfoTest, ValidModelInfo) { - const std::string name_op[] = { - "contains", - "beginwith", - "endwith", - "=" - }; - const std::string version_op[] = { - "=", - "<", - "<=", - ">", - ">=", - "any", - "between" - }; - for (size_t i = 0; i < arraysize(name_op); ++i) { - for (size_t j = 0; j < arraysize(version_op); ++j) { - std::string version1; - std::string version2; - if (version_op[j] != "any") - version1 = "3.14"; - if (version_op[j] == "between") - version2 = "5.4"; - MachineModelInfo info(name_op[i], "model", - version_op[j], version1, version2); - EXPECT_TRUE(info.IsValid()); - } - } -} - -TEST_F(MachineModelInfoTest, ModelComparison) { - MachineModelInfo info("=", "model_a", ">", "3.4", std::string()); - EXPECT_TRUE(info.Contains("model_a", "4")); - EXPECT_FALSE(info.Contains("model_b", "4")); - EXPECT_FALSE(info.Contains("model_a", "3.2")); -} - -} // namespace content - diff --git a/content/browser/gpu/gpu_control_list_number_info_unittest.cc b/content/browser/gpu/gpu_control_list_number_info_unittest.cc deleted file mode 100644 index 0cb72a7dd4..0000000000 --- a/content/browser/gpu/gpu_control_list_number_info_unittest.cc +++ /dev/null @@ -1,210 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/browser/gpu/gpu_control_list.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace content { - -class NumberInfoTest : public testing::Test { - public: - NumberInfoTest() { } - virtual ~NumberInfoTest() { } - - typedef GpuControlList::FloatInfo FloatInfo; - typedef GpuControlList::IntInfo IntInfo; -}; - -TEST_F(NumberInfoTest, ValidFloatInfo) { - const std::string op[] = { - "=", - "<", - "<=", - ">", - ">=", - "any", - "between" - }; - for (size_t i = 0; i < arraysize(op); ++i) { - std::string value1; - std::string value2; - if (op[i] != "any") - value1 = "3.14"; - if (op[i] == "between") - value2 = "4.21"; - FloatInfo info(op[i], value1, value2); - EXPECT_TRUE(info.IsValid()); - } - - const std::string value[] = { - "1.0E12", - "1.0e12", - "2013", - "1.0e-12", - "2.1400", - "-2.14", - }; - for (size_t i = 0; i < arraysize(value); ++i) { - FloatInfo info("=", value[i], std::string()); - EXPECT_TRUE(info.IsValid()); - } -} - -TEST_F(NumberInfoTest, InvalidFloatInfo) { - const std::string op[] = { - "=", - "<", - "<=", - ">", - ">=", - }; - for (size_t i = 0; i < arraysize(op); ++i) { - FloatInfo info(op[i], std::string(), std::string()); - EXPECT_FALSE(info.IsValid()); - } - { - FloatInfo info("between", "3.14", std::string()); - EXPECT_FALSE(info.IsValid()); - } - const std::string value[] = { - "1.0 E12", - "1.0e 12", - " 2013", - "2013 ", - "- 2.14", - }; - for (size_t i = 0; i < arraysize(value); ++i) { - FloatInfo info("=", value[i], std::string()); - EXPECT_FALSE(info.IsValid()); - } -} - -TEST_F(NumberInfoTest, FloatComparison) { - { - FloatInfo info("=", "3.14", std::string()); - EXPECT_TRUE(info.Contains(3.14f)); - EXPECT_TRUE(info.Contains(3.1400f)); - EXPECT_FALSE(info.Contains(3.1f)); - EXPECT_FALSE(info.Contains(3)); - } - { - FloatInfo info(">", "3.14", std::string()); - EXPECT_FALSE(info.Contains(3.14f)); - EXPECT_TRUE(info.Contains(3.141f)); - EXPECT_FALSE(info.Contains(3.1f)); - } - { - FloatInfo info("<=", "3.14", std::string()); - EXPECT_TRUE(info.Contains(3.14f)); - EXPECT_FALSE(info.Contains(3.141f)); - EXPECT_TRUE(info.Contains(3.1f)); - } - { - FloatInfo info("any", std::string(), std::string()); - EXPECT_TRUE(info.Contains(3.14f)); - } - { - FloatInfo info("between", "3.14", "5.4"); - EXPECT_TRUE(info.Contains(3.14f)); - EXPECT_TRUE(info.Contains(5.4f)); - EXPECT_TRUE(info.Contains(4)); - EXPECT_FALSE(info.Contains(5.6f)); - EXPECT_FALSE(info.Contains(3.12f)); - } -} - -TEST_F(NumberInfoTest, ValidIntInfo) { - const std::string op[] = { - "=", - "<", - "<=", - ">", - ">=", - "any", - "between" - }; - for (size_t i = 0; i < arraysize(op); ++i) { - std::string value1; - std::string value2; - if (op[i] != "any") - value1 = "3"; - if (op[i] == "between") - value2 = "9"; - IntInfo info(op[i], value1, value2); - EXPECT_TRUE(info.IsValid()); - } - - const std::string value[] = { - "12", - "-12", - }; - for (size_t i = 0; i < arraysize(value); ++i) { - IntInfo info("=", value[i], std::string()); - EXPECT_TRUE(info.IsValid()); - } -} - -TEST_F(NumberInfoTest, InvalidIntInfo) { - const std::string op[] = { - "=", - "<", - "<=", - ">", - ">=", - }; - for (size_t i = 0; i < arraysize(op); ++i) { - IntInfo info(op[i], std::string(), std::string()); - EXPECT_FALSE(info.IsValid()); - } - { - IntInfo info("between", "3", std::string()); - EXPECT_FALSE(info.IsValid()); - } - const std::string value[] = { - " 12", - "12 ", - "- 12", - " -12", - "3.14" - }; - for (size_t i = 0; i < arraysize(value); ++i) { - IntInfo info("=", value[i], std::string()); - EXPECT_FALSE(info.IsValid()); - } -} - -TEST_F(NumberInfoTest, IntComparison) { - { - IntInfo info("=", "3", std::string()); - EXPECT_TRUE(info.Contains(3)); - EXPECT_FALSE(info.Contains(4)); - } - { - IntInfo info(">", "3", std::string()); - EXPECT_FALSE(info.Contains(2)); - EXPECT_FALSE(info.Contains(3)); - EXPECT_TRUE(info.Contains(4)); - } - { - IntInfo info("<=", "3", std::string()); - EXPECT_TRUE(info.Contains(2)); - EXPECT_TRUE(info.Contains(3)); - EXPECT_FALSE(info.Contains(4)); - } - { - IntInfo info("any", std::string(), std::string()); - EXPECT_TRUE(info.Contains(3)); - } - { - IntInfo info("between", "3", "5"); - EXPECT_TRUE(info.Contains(3)); - EXPECT_TRUE(info.Contains(5)); - EXPECT_TRUE(info.Contains(4)); - EXPECT_FALSE(info.Contains(6)); - EXPECT_FALSE(info.Contains(2)); - } -} - -} // namespace content - diff --git a/content/browser/gpu/gpu_control_list_os_info_unittest.cc b/content/browser/gpu/gpu_control_list_os_info_unittest.cc deleted file mode 100644 index 5ea03b2835..0000000000 --- a/content/browser/gpu/gpu_control_list_os_info_unittest.cc +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/browser/gpu/gpu_control_list.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace content { - -class OsInfoTest : public testing::Test { - public: - OsInfoTest() { } - virtual ~OsInfoTest() { } - - typedef GpuControlList::OsInfo OsInfo; -}; - -TEST_F(OsInfoTest, ValidOsInfo) { - const std::string os[] = { - "win", - "linux", - "macosx", - "chromeos", - "android", - "any" - }; - const GpuControlList::OsType os_type[] = { - GpuControlList::kOsWin, - GpuControlList::kOsLinux, - GpuControlList::kOsMacosx, - GpuControlList::kOsChromeOS, - GpuControlList::kOsAndroid, - GpuControlList::kOsAny - }; - for (size_t i = 0; i < arraysize(os); ++i) { - OsInfo info(os[i], "=", "10.6", std::string()); - EXPECT_TRUE(info.IsValid()); - EXPECT_EQ(os_type[i], info.type()); - } - { - OsInfo info("any", "any", std::string(), std::string()); - EXPECT_TRUE(info.IsValid()); - } -} - -TEST_F(OsInfoTest, InvalidOsInfo) { - const std::string os[] = { - "win", - "linux", - "macosx", - "chromeos", - "android", - "any" - }; - for (size_t i = 0; i < arraysize(os); ++i) { - { - OsInfo info(os[i], std::string(), std::string(), std::string()); - EXPECT_FALSE(info.IsValid()); - } - { - OsInfo info(os[i], "=", std::string(), std::string()); - EXPECT_FALSE(info.IsValid()); - } - { - OsInfo info(os[i], std::string(), "10.6", std::string()); - EXPECT_FALSE(info.IsValid()); - } - } - const std::string os_cap[] = { - "Win", - "Linux", - "MacOSX", - "ChromeOS", - "Android", - }; - for (size_t i = 0; i < arraysize(os_cap); ++i) { - OsInfo info(os_cap[i], "=", "10.6", std::string()); - EXPECT_FALSE(info.IsValid()); - } -} - -TEST_F(OsInfoTest, OsComparison) { - { - OsInfo info("any", "any", std::string(), std::string()); - const GpuControlList::OsType os_type[] = { - GpuControlList::kOsWin, GpuControlList::kOsLinux, - GpuControlList::kOsMacosx, GpuControlList::kOsChromeOS, - GpuControlList::kOsAndroid, - }; - for (size_t i = 0; i < arraysize(os_type); ++i) { - EXPECT_TRUE(info.Contains(os_type[i], std::string())); - EXPECT_TRUE(info.Contains(os_type[i], "7.8")); - } - } - { - OsInfo info("win", ">=", "6", std::string()); - EXPECT_FALSE(info.Contains(GpuControlList::kOsMacosx, "10.8.3")); - EXPECT_FALSE(info.Contains(GpuControlList::kOsLinux, "10")); - EXPECT_FALSE(info.Contains(GpuControlList::kOsChromeOS, "13")); - EXPECT_FALSE(info.Contains(GpuControlList::kOsAndroid, "7")); - EXPECT_FALSE(info.Contains(GpuControlList::kOsAny, "7")); - EXPECT_FALSE(info.Contains(GpuControlList::kOsWin, std::string())); - EXPECT_TRUE(info.Contains(GpuControlList::kOsWin, "6")); - EXPECT_TRUE(info.Contains(GpuControlList::kOsWin, "6.1")); - EXPECT_TRUE(info.Contains(GpuControlList::kOsWin, "7")); - EXPECT_FALSE(info.Contains(GpuControlList::kOsWin, "5")); - } -} - -} // namespace content - diff --git a/content/browser/gpu/gpu_control_list_string_info_unittest.cc b/content/browser/gpu/gpu_control_list_string_info_unittest.cc deleted file mode 100644 index c2c80094ac..0000000000 --- a/content/browser/gpu/gpu_control_list_string_info_unittest.cc +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/browser/gpu/gpu_control_list.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace content { - -class StringInfoTest : public testing::Test { - public: - StringInfoTest() { } - virtual ~StringInfoTest() { } - - typedef GpuControlList::StringInfo StringInfo; -}; - -TEST_F(StringInfoTest, ValidStringInfo) { - const std::string op[] = { - "contains", - "beginwith", - "endwith", - "=" - }; - for (size_t i = 0; i < arraysize(op); ++i) { - { - StringInfo info(op[i], std::string()); - EXPECT_TRUE(info.IsValid()); - } - { - StringInfo info(op[i], "hello"); - EXPECT_TRUE(info.IsValid()); - } - } -} - -TEST_F(StringInfoTest, InvalidStringInfo) { - const std::string op[] = { - "Contains", - "BeginWith", - "EndWith", - " =", - "= " - }; - for (size_t i = 0; i < arraysize(op); ++i) { - StringInfo info(op[i], "hello"); - EXPECT_FALSE(info.IsValid()); - } -} - -TEST_F(StringInfoTest, StringComparison) { - { - StringInfo info("contains", "happy"); - EXPECT_TRUE(info.Contains("unhappy")); - EXPECT_TRUE(info.Contains("happy1")); - EXPECT_TRUE(info.Contains("happy")); - EXPECT_TRUE(info.Contains("a happy dog")); - EXPECT_TRUE(info.Contains("Happy")); - EXPECT_TRUE(info.Contains("HAPPY")); - EXPECT_FALSE(info.Contains("ha-ppy")); - } - { - StringInfo info("beginwith", "happy"); - EXPECT_FALSE(info.Contains("unhappy")); - EXPECT_TRUE(info.Contains("happy1")); - EXPECT_TRUE(info.Contains("happy")); - EXPECT_FALSE(info.Contains("a happy dog")); - EXPECT_TRUE(info.Contains("Happy")); - EXPECT_TRUE(info.Contains("HAPPY")); - EXPECT_FALSE(info.Contains("ha-ppy")); - } - { - StringInfo info("endwith", "happy"); - EXPECT_TRUE(info.Contains("unhappy")); - EXPECT_FALSE(info.Contains("happy1")); - EXPECT_TRUE(info.Contains("happy")); - EXPECT_FALSE(info.Contains("a happy dog")); - EXPECT_TRUE(info.Contains("Happy")); - EXPECT_TRUE(info.Contains("HAPPY")); - EXPECT_FALSE(info.Contains("ha-ppy")); - } - { - StringInfo info("=", "happy"); - EXPECT_FALSE(info.Contains("unhappy")); - EXPECT_FALSE(info.Contains("happy1")); - EXPECT_TRUE(info.Contains("happy")); - EXPECT_FALSE(info.Contains("a happy dog")); - EXPECT_TRUE(info.Contains("Happy")); - EXPECT_TRUE(info.Contains("HAPPY")); - EXPECT_FALSE(info.Contains("ha-ppy")); - EXPECT_FALSE(info.Contains("ha ppy")); - EXPECT_FALSE(info.Contains(" happy")); - EXPECT_FALSE(info.Contains("happy ")); - } -} - -} // namespace content - diff --git a/content/browser/gpu/gpu_control_list_unittest.cc b/content/browser/gpu/gpu_control_list_unittest.cc deleted file mode 100644 index 0991d27155..0000000000 --- a/content/browser/gpu/gpu_control_list_unittest.cc +++ /dev/null @@ -1,444 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <vector> - -#include "base/memory/scoped_ptr.h" -#include "content/browser/gpu/gpu_control_list.h" -#include "content/public/common/gpu_info.h" -#include "testing/gtest/include/gtest/gtest.h" - -const char kOsVersion[] = "10.6.4"; -const uint32 kIntelVendorId = 0x8086; -const uint32 kIntelDeviceId = 0x0166; // 3rd Gen Core Graphics -const uint32 kNvidiaVendorId = 0x10de; -const uint32 kNvidiaDeviceId = 0x0fd5; // GeForce GT 650M - -#define LONG_STRING_CONST(...) #__VA_ARGS__ - -#define EXPECT_EMPTY_SET(feature_set) EXPECT_EQ(0u, feature_set.size()) -#define EXPECT_SINGLE_FEATURE(feature_set, feature) \ - EXPECT_TRUE(feature_set.size() == 1 && feature_set.count(feature) == 1) - -namespace content { - -enum TestFeatureType { - TEST_FEATURE_0 = 1, - TEST_FEATURE_1 = 1 << 2, - TEST_FEATURE_2 = 1 << 3, -}; - -class GpuControlListTest : public testing::Test { - public: - GpuControlListTest() { } - - virtual ~GpuControlListTest() { } - - const GPUInfo& gpu_info() const { - return gpu_info_; - } - - GpuControlList* Create() { - GpuControlList* rt = new GpuControlList(); - rt->AddSupportedFeature("test_feature_0", TEST_FEATURE_0); - rt->AddSupportedFeature("test_feature_1", TEST_FEATURE_1); - rt->AddSupportedFeature("test_feature_2", TEST_FEATURE_2); - return rt; - } - - protected: - virtual void SetUp() { - gpu_info_.gpu.vendor_id = kNvidiaVendorId; - gpu_info_.gpu.device_id = 0x0640; - gpu_info_.driver_vendor = "NVIDIA"; - gpu_info_.driver_version = "1.6.18"; - gpu_info_.driver_date = "7-14-2009"; - gpu_info_.machine_model = "MacBookPro 7.1"; - gpu_info_.gl_vendor = "NVIDIA Corporation"; - gpu_info_.gl_renderer = "NVIDIA GeForce GT 120 OpenGL Engine"; - gpu_info_.performance_stats.graphics = 5.0; - gpu_info_.performance_stats.gaming = 5.0; - gpu_info_.performance_stats.overall = 5.0; - } - - virtual void TearDown() { - } - - private: - GPUInfo gpu_info_; -}; - -TEST_F(GpuControlListTest, DefaultControlListSettings) { - scoped_ptr<GpuControlList> control_list(Create()); - // Default control list settings: all feature are allowed. - std::set<int> features = control_list->MakeDecision( - GpuControlList::kOsMacosx, kOsVersion, gpu_info()); - EXPECT_EMPTY_SET(features); -} - -TEST_F(GpuControlListTest, EmptyControlList) { - // Empty list: all features are allowed. - const std::string empty_list_json = LONG_STRING_CONST( - { - "name": "gpu control list", - "version": "2.5", - "entries": [ - ] - } - ); - scoped_ptr<GpuControlList> control_list(Create()); - - EXPECT_TRUE(control_list->LoadList(empty_list_json, - GpuControlList::kAllOs)); - EXPECT_EQ("2.5", control_list->version()); - std::set<int> features = control_list->MakeDecision( - GpuControlList::kOsMacosx, kOsVersion, gpu_info()); - EXPECT_EMPTY_SET(features); -} - -TEST_F(GpuControlListTest, DetailedEntryAndInvalidJson) { - // exact setting. - const std::string exact_list_json = LONG_STRING_CONST( - { - "name": "gpu control list", - "version": "0.1", - "entries": [ - { - "id": 5, - "os": { - "type": "macosx", - "version": { - "op": "=", - "number": "10.6.4" - } - }, - "vendor_id": "0x10de", - "device_id": ["0x0640"], - "driver_version": { - "op": "=", - "number": "1.6.18" - }, - "features": [ - "test_feature_0" - ] - } - ] - } - ); - scoped_ptr<GpuControlList> control_list(Create()); - - EXPECT_TRUE(control_list->LoadList(exact_list_json, GpuControlList::kAllOs)); - std::set<int> features = control_list->MakeDecision( - GpuControlList::kOsMacosx, kOsVersion, gpu_info()); - EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0); - - // Invalid json input should not change the current control_list settings. - const std::string invalid_json = "invalid"; - - EXPECT_FALSE(control_list->LoadList(invalid_json, GpuControlList::kAllOs)); - features = control_list->MakeDecision( - GpuControlList::kOsMacosx, kOsVersion, gpu_info()); - EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0); - std::vector<uint32> entries; - control_list->GetDecisionEntries(&entries, false); - ASSERT_EQ(1u, entries.size()); - EXPECT_EQ(5u, entries[0]); - EXPECT_EQ(5u, control_list->max_entry_id()); -} - -TEST_F(GpuControlListTest, VendorOnAllOsEntry) { - // ControlList a vendor on all OS. - const std::string vendor_json = LONG_STRING_CONST( - { - "name": "gpu control list", - "version": "0.1", - "entries": [ - { - "id": 1, - "vendor_id": "0x10de", - "features": [ - "test_feature_0" - ] - } - ] - } - ); - scoped_ptr<GpuControlList> control_list(Create()); - - // ControlList entries won't be filtered to the current OS only upon loading. - EXPECT_TRUE(control_list->LoadList(vendor_json, GpuControlList::kAllOs)); - std::set<int> features = control_list->MakeDecision( - GpuControlList::kOsMacosx, kOsVersion, gpu_info()); - EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0); - features = control_list->MakeDecision( - GpuControlList::kOsWin, kOsVersion, gpu_info()); - EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0); - features = control_list->MakeDecision( - GpuControlList::kOsLinux, kOsVersion, gpu_info()); - EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0); -#if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_MACOSX) || \ - defined(OS_OPENBSD) - // ControlList entries will be filtered to the current OS only upon loading. - EXPECT_TRUE(control_list->LoadList( - vendor_json, GpuControlList::kCurrentOsOnly)); - features = control_list->MakeDecision( - GpuControlList::kOsMacosx, kOsVersion, gpu_info()); - EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0); - features = control_list->MakeDecision( - GpuControlList::kOsWin, kOsVersion, gpu_info()); - EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0); - features = control_list->MakeDecision( - GpuControlList::kOsLinux, kOsVersion, gpu_info()); - EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0); -#endif -} - -TEST_F(GpuControlListTest, ChromeVersionEntry) { - const std::string browser_version_json = LONG_STRING_CONST( - { - "name": "gpu control list", - "version": "0.1", - "entries": [ - { - "id": 1, - "browser_version": { - "op": ">=", - "number": "10" - }, - "features": [ - "test_feature_0" - ] - } - ] - } - ); - scoped_ptr<GpuControlList> control_list9(Create()); - EXPECT_TRUE(control_list9->LoadList( - "9.0", browser_version_json, GpuControlList::kAllOs)); - std::set<int> features = control_list9->MakeDecision( - GpuControlList::kOsWin, kOsVersion, gpu_info()); - EXPECT_EMPTY_SET(features); - - scoped_ptr<GpuControlList> control_list10(Create()); - EXPECT_TRUE(control_list10->LoadList( - "10.0", browser_version_json, GpuControlList::kAllOs)); - features = control_list10->MakeDecision( - GpuControlList::kOsWin, kOsVersion, gpu_info()); - EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0); -} - -TEST_F(GpuControlListTest, UnknownField) { - const std::string unknown_field_json = LONG_STRING_CONST( - { - "name": "gpu control list", - "version": "0.1", - "entries": [ - { - "id": 1, - "unknown_field": 0, - "features": [ - "test_feature_1" - ] - }, - { - "id": 2, - "features": [ - "test_feature_0" - ] - } - ] - } - ); - scoped_ptr<GpuControlList> control_list(Create()); - - EXPECT_TRUE(control_list->LoadList( - unknown_field_json, GpuControlList::kAllOs)); - EXPECT_EQ(1u, control_list->num_entries()); - EXPECT_TRUE(control_list->contains_unknown_fields()); - std::set<int> features = control_list->MakeDecision( - GpuControlList::kOsWin, kOsVersion, gpu_info()); - EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0); -} - -TEST_F(GpuControlListTest, UnknownExceptionField) { - const std::string unknown_exception_field_json = LONG_STRING_CONST( - { - "name": "gpu control list", - "version": "0.1", - "entries": [ - { - "id": 1, - "unknown_field": 0, - "features": [ - "test_feature_2" - ] - }, - { - "id": 2, - "exceptions": [ - { - "unknown_field": 0 - } - ], - "features": [ - "test_feature_1" - ] - }, - { - "id": 3, - "features": [ - "test_feature_0" - ] - } - ] - } - ); - scoped_ptr<GpuControlList> control_list(Create()); - - EXPECT_TRUE(control_list->LoadList( - unknown_exception_field_json, GpuControlList::kAllOs)); - EXPECT_EQ(1u, control_list->num_entries()); - EXPECT_TRUE(control_list->contains_unknown_fields()); - std::set<int> features = control_list->MakeDecision( - GpuControlList::kOsWin, kOsVersion, gpu_info()); - EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0); -} - -TEST_F(GpuControlListTest, DisabledEntry) { - const std::string disabled_json = LONG_STRING_CONST( - { - "name": "gpu control list", - "version": "0.1", - "entries": [ - { - "id": 1, - "disabled": true, - "features": [ - "test_feature_0" - ] - } - ] - } - ); - scoped_ptr<GpuControlList> control_list(Create()); - EXPECT_TRUE(control_list->LoadList(disabled_json, GpuControlList::kAllOs)); - std::set<int> features = control_list->MakeDecision( - GpuControlList::kOsWin, kOsVersion, gpu_info()); - EXPECT_EMPTY_SET(features); - std::vector<uint32> flag_entries; - control_list->GetDecisionEntries(&flag_entries, false); - EXPECT_EQ(0u, flag_entries.size()); - control_list->GetDecisionEntries(&flag_entries, true); - EXPECT_EQ(1u, flag_entries.size()); -} - -TEST_F(GpuControlListTest, NeedsMoreInfoForExceptions) { - const std::string json = LONG_STRING_CONST( - { - "name": "gpu control list", - "version": "0.1", - "entries": [ - { - "id": 1, - "os": { - "type": "linux" - }, - "vendor_id": "0x8086", - "exceptions": [ - { - "gl_renderer": { - "op": "contains", - "value": "mesa" - } - } - ], - "features": [ - "test_feature_0" - ] - } - ] - } - ); - GPUInfo gpu_info; - gpu_info.gpu.vendor_id = kIntelVendorId; - - scoped_ptr<GpuControlList> control_list(Create()); - EXPECT_TRUE(control_list->LoadList(json, GpuControlList::kAllOs)); - - // The case this entry does not apply. - std::set<int> features = control_list->MakeDecision( - GpuControlList::kOsMacosx, kOsVersion, gpu_info); - EXPECT_EMPTY_SET(features); - EXPECT_FALSE(control_list->needs_more_info()); - - // The case this entry might apply, but need more info. - features = control_list->MakeDecision( - GpuControlList::kOsLinux, kOsVersion, gpu_info); - EXPECT_EMPTY_SET(features); - EXPECT_TRUE(control_list->needs_more_info()); - - // The case we have full info, and the exception applies (so the entry - // does not apply). - gpu_info.gl_renderer = "mesa"; - features = control_list->MakeDecision( - GpuControlList::kOsLinux, kOsVersion, gpu_info); - EXPECT_EMPTY_SET(features); - EXPECT_FALSE(control_list->needs_more_info()); - - // The case we have full info, and this entry applies. - gpu_info.gl_renderer = "my renderer"; - features = control_list->MakeDecision(GpuControlList::kOsLinux, kOsVersion, - gpu_info); - EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0); - EXPECT_FALSE(control_list->needs_more_info()); -} - -TEST_F(GpuControlListTest, IgnorableEntries) { - // If an entry will not change the control_list decisions, then it should not - // trigger the needs_more_info flag. - const std::string json = LONG_STRING_CONST( - { - "name": "gpu control list", - "version": "0.1", - "entries": [ - { - "id": 1, - "os": { - "type": "linux" - }, - "vendor_id": "0x8086", - "features": [ - "test_feature_0" - ] - }, - { - "id": 2, - "os": { - "type": "linux" - }, - "vendor_id": "0x8086", - "driver_version": { - "op": "<", - "number": "10.7" - }, - "features": [ - "test_feature_0" - ] - } - ] - } - ); - GPUInfo gpu_info; - gpu_info.gpu.vendor_id = kIntelVendorId; - - scoped_ptr<GpuControlList> control_list(Create()); - EXPECT_TRUE(control_list->LoadList(json, GpuControlList::kAllOs)); - std::set<int> features = control_list->MakeDecision( - GpuControlList::kOsLinux, kOsVersion, gpu_info); - EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0); - EXPECT_FALSE(control_list->needs_more_info()); -} - -} // namespace content - diff --git a/content/browser/gpu/gpu_control_list_version_info_unittest.cc b/content/browser/gpu/gpu_control_list_version_info_unittest.cc deleted file mode 100644 index eb1864873e..0000000000 --- a/content/browser/gpu/gpu_control_list_version_info_unittest.cc +++ /dev/null @@ -1,258 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/browser/gpu/gpu_control_list.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace content { - -class VersionInfoTest : public testing::Test { - public: - VersionInfoTest() { } - virtual ~VersionInfoTest() { } - - typedef GpuControlList::VersionInfo VersionInfo; -}; - -TEST_F(VersionInfoTest, ValidVersionInfo) { - const std::string op[] = { - "=", - "<", - "<=", - ">", - ">=", - "any", - "between" - }; - for (size_t i = 0; i < arraysize(op); ++i) { - std::string string1; - std::string string2; - if (op[i] != "any") - string1 = "8.9"; - if (op[i] == "between") - string2 = "9.0"; - VersionInfo info(op[i], std::string(), string1, string2); - EXPECT_TRUE(info.IsValid()); - } - - const std::string style[] = { - "lexical", - "numerical", - "" // Default, same as "numerical" - }; - for (size_t i =0; i < arraysize(style); ++i) { - VersionInfo info("=", style[i], "8.9", std::string()); - EXPECT_TRUE(info.IsValid()); - if (style[i] == "lexical") - EXPECT_TRUE(info.IsLexical()); - else - EXPECT_FALSE(info.IsLexical()); - } - - const std::string number[] = { - "10", - "10.9", - "10.0", - "10.0.9", - "0.8", - // Leading 0s are valid. - "10.09", - // Whitespaces are ignored. - " 10.9", - "10.9 ", - "10 .9", - "10. 9", - }; - for (size_t i =0; i < arraysize(number); ++i) { - VersionInfo info("=", std::string(), number[i], std::string()); - EXPECT_TRUE(info.IsValid()); - } -} - -TEST_F(VersionInfoTest, InvalidVersionInfo) { - const std::string op[] = { - "=", - "<", - "<=", - ">", - ">=", - "any", - "between" - }; - for (size_t i = 0; i < arraysize(op); ++i) { - { - VersionInfo info(op[i], std::string(), "8.9", std::string()); - if (op[i] == "between") - EXPECT_FALSE(info.IsValid()); - else - EXPECT_TRUE(info.IsValid()); - } - { - VersionInfo info(op[i], std::string(), std::string(), std::string()); - if (op[i] == "any") - EXPECT_TRUE(info.IsValid()); - else - EXPECT_FALSE(info.IsValid()); - } - { - VersionInfo info(op[i], std::string(), "8.9", "9.0"); - EXPECT_TRUE(info.IsValid()); - } - } - - const std::string number[] = { - "8.E", - "8-9", - }; - for (size_t i = 0; i < arraysize(number); ++i) { - VersionInfo info("=", std::string(), number[i], std::string()); - EXPECT_FALSE(info.IsValid()); - } -} - -TEST_F(VersionInfoTest, VersionComparison) { - { - VersionInfo info("any", std::string(), std::string(), std::string()); - EXPECT_TRUE(info.Contains("0")); - EXPECT_TRUE(info.Contains("8.9")); - EXPECT_TRUE(info.Contains("100")); - } - { - VersionInfo info(">", std::string(), "8.9", std::string()); - EXPECT_FALSE(info.Contains("7")); - EXPECT_FALSE(info.Contains("8.9")); - EXPECT_FALSE(info.Contains("8.9.1")); - EXPECT_TRUE(info.Contains("9")); - } - { - VersionInfo info(">=", std::string(), "8.9", std::string()); - EXPECT_FALSE(info.Contains("7")); - EXPECT_TRUE(info.Contains("8.9")); - EXPECT_TRUE(info.Contains("8.9.1")); - EXPECT_TRUE(info.Contains("9")); - } - { - VersionInfo info("=", std::string(), "8.9", std::string()); - EXPECT_FALSE(info.Contains("7")); - EXPECT_TRUE(info.Contains("8")); - EXPECT_TRUE(info.Contains("8.9")); - EXPECT_TRUE(info.Contains("8.9.1")); - EXPECT_FALSE(info.Contains("9")); - } - { - VersionInfo info("<", std::string(), "8.9", std::string()); - EXPECT_TRUE(info.Contains("7")); - EXPECT_TRUE(info.Contains("8.8")); - EXPECT_FALSE(info.Contains("8")); - EXPECT_FALSE(info.Contains("8.9")); - EXPECT_FALSE(info.Contains("8.9.1")); - EXPECT_FALSE(info.Contains("9")); - } - { - VersionInfo info("<=", std::string(), "8.9", std::string()); - EXPECT_TRUE(info.Contains("7")); - EXPECT_TRUE(info.Contains("8.8")); - EXPECT_TRUE(info.Contains("8")); - EXPECT_TRUE(info.Contains("8.9")); - EXPECT_TRUE(info.Contains("8.9.1")); - EXPECT_FALSE(info.Contains("9")); - } - { - VersionInfo info("between", std::string(), "8.9", "9.1"); - EXPECT_FALSE(info.Contains("7")); - EXPECT_FALSE(info.Contains("8.8")); - EXPECT_TRUE(info.Contains("8")); - EXPECT_TRUE(info.Contains("8.9")); - EXPECT_TRUE(info.Contains("8.9.1")); - EXPECT_TRUE(info.Contains("9")); - EXPECT_TRUE(info.Contains("9.1")); - EXPECT_TRUE(info.Contains("9.1.9")); - EXPECT_FALSE(info.Contains("9.2")); - EXPECT_FALSE(info.Contains("10")); - } -} - -TEST_F(VersionInfoTest, DateComparison) { - // When we use '-' as splitter, we assume a format of mm-dd-yyyy - // or mm-yyyy, i.e., a date. - { - VersionInfo info("=", std::string(), "1976.3.21", std::string()); - EXPECT_TRUE(info.Contains("3-21-1976", '-')); - EXPECT_TRUE(info.Contains("3-1976", '-')); - EXPECT_TRUE(info.Contains("03-1976", '-')); - EXPECT_FALSE(info.Contains("21-3-1976", '-')); - } - { - VersionInfo info(">", std::string(), "1976.3.21", std::string()); - EXPECT_TRUE(info.Contains("3-22-1976", '-')); - EXPECT_TRUE(info.Contains("4-1976", '-')); - EXPECT_TRUE(info.Contains("04-1976", '-')); - EXPECT_FALSE(info.Contains("3-1976", '-')); - EXPECT_FALSE(info.Contains("2-1976", '-')); - } - { - VersionInfo info("between", std::string(), "1976.3.21", "2012.12.25"); - EXPECT_FALSE(info.Contains("3-20-1976", '-')); - EXPECT_TRUE(info.Contains("3-21-1976", '-')); - EXPECT_TRUE(info.Contains("3-22-1976", '-')); - EXPECT_TRUE(info.Contains("3-1976", '-')); - EXPECT_TRUE(info.Contains("4-1976", '-')); - EXPECT_TRUE(info.Contains("1-1-2000", '-')); - EXPECT_TRUE(info.Contains("1-2000", '-')); - EXPECT_TRUE(info.Contains("2000", '-')); - EXPECT_TRUE(info.Contains("11-2012", '-')); - EXPECT_TRUE(info.Contains("12-2012", '-')); - EXPECT_TRUE(info.Contains("12-24-2012", '-')); - EXPECT_TRUE(info.Contains("12-25-2012", '-')); - EXPECT_FALSE(info.Contains("12-26-2012", '-')); - EXPECT_FALSE(info.Contains("1-2013", '-')); - EXPECT_FALSE(info.Contains("2013", '-')); - } -} - -TEST_F(VersionInfoTest, LexicalComparison) { - // When we use lexical style, we assume a format major.minor.*. - // We apply numerical comparison to major, lexical comparison to others. - { - VersionInfo info("<", "lexical", "8.201", std::string()); - EXPECT_TRUE(info.Contains("8.001.100")); - EXPECT_TRUE(info.Contains("8.109")); - EXPECT_TRUE(info.Contains("8.10900")); - EXPECT_TRUE(info.Contains("8.109.100")); - EXPECT_TRUE(info.Contains("8.2")); - EXPECT_TRUE(info.Contains("8.20")); - EXPECT_TRUE(info.Contains("8.200")); - EXPECT_TRUE(info.Contains("8.20.100")); - EXPECT_FALSE(info.Contains("8.201")); - EXPECT_FALSE(info.Contains("8.2010")); - EXPECT_FALSE(info.Contains("8.21")); - EXPECT_FALSE(info.Contains("8.21.100")); - EXPECT_FALSE(info.Contains("9.002")); - EXPECT_FALSE(info.Contains("9.201")); - EXPECT_FALSE(info.Contains("12")); - EXPECT_FALSE(info.Contains("12.201")); - } - { - VersionInfo info("<", "lexical", "9.002", std::string()); - EXPECT_TRUE(info.Contains("8.001.100")); - EXPECT_TRUE(info.Contains("8.109")); - EXPECT_TRUE(info.Contains("8.10900")); - EXPECT_TRUE(info.Contains("8.109.100")); - EXPECT_TRUE(info.Contains("8.2")); - EXPECT_TRUE(info.Contains("8.20")); - EXPECT_TRUE(info.Contains("8.200")); - EXPECT_TRUE(info.Contains("8.20.100")); - EXPECT_TRUE(info.Contains("8.201")); - EXPECT_TRUE(info.Contains("8.2010")); - EXPECT_TRUE(info.Contains("8.21")); - EXPECT_TRUE(info.Contains("8.21.100")); - EXPECT_FALSE(info.Contains("9.002")); - EXPECT_FALSE(info.Contains("9.201")); - EXPECT_FALSE(info.Contains("12")); - EXPECT_FALSE(info.Contains("12.201")); - } -} - -} // namespace content - diff --git a/content/browser/gpu/gpu_data_manager_impl.cc b/content/browser/gpu/gpu_data_manager_impl.cc index f53094e775..87a34d24e3 100644 --- a/content/browser/gpu/gpu_data_manager_impl.cc +++ b/content/browser/gpu/gpu_data_manager_impl.cc @@ -19,7 +19,7 @@ GpuDataManagerImpl* GpuDataManagerImpl::GetInstance() { } void GpuDataManagerImpl::InitializeForTesting( - const std::string& gpu_blacklist_json, const GPUInfo& gpu_info) { + const std::string& gpu_blacklist_json, const gpu::GPUInfo& gpu_info) { base::AutoLock auto_lock(lock_); private_->InitializeForTesting(gpu_blacklist_json, gpu_info); } @@ -29,7 +29,7 @@ bool GpuDataManagerImpl::IsFeatureBlacklisted(int feature) const { return private_->IsFeatureBlacklisted(feature); } -GPUInfo GpuDataManagerImpl::GetGPUInfo() const { +gpu::GPUInfo GpuDataManagerImpl::GetGPUInfo() const { base::AutoLock auto_lock(lock_); return private_->GetGPUInfo(); } @@ -117,7 +117,7 @@ void GpuDataManagerImpl::Initialize() { private_->Initialize(); } -void GpuDataManagerImpl::UpdateGpuInfo(const GPUInfo& gpu_info) { +void GpuDataManagerImpl::UpdateGpuInfo(const gpu::GPUInfo& gpu_info) { base::AutoLock auto_lock(lock_); private_->UpdateGpuInfo(gpu_info); } @@ -152,7 +152,7 @@ void GpuDataManagerImpl::UpdateRendererWebPrefs( private_->UpdateRendererWebPrefs(prefs); } -GpuSwitchingOption GpuDataManagerImpl::GetGpuSwitchingOption() const { +gpu::GpuSwitchingOption GpuDataManagerImpl::GetGpuSwitchingOption() const { base::AutoLock auto_lock(lock_); return private_->GetGpuSwitchingOption(); } diff --git a/content/browser/gpu/gpu_data_manager_impl.h b/content/browser/gpu/gpu_data_manager_impl.h index 32ff23bd9c..2e6567a005 100644 --- a/content/browser/gpu/gpu_data_manager_impl.h +++ b/content/browser/gpu/gpu_data_manager_impl.h @@ -18,10 +18,10 @@ #include "base/time.h" #include "base/values.h" #include "content/public/browser/gpu_data_manager.h" -#include "content/public/common/gpu_info.h" #include "content/public/common/gpu_memory_stats.h" -#include "content/public/common/gpu_switching_option.h" #include "content/public/common/three_d_api_types.h" +#include "gpu/config/gpu_info.h" +#include "gpu/config/gpu_switching_option.h" class CommandLine; class GURL; @@ -58,9 +58,9 @@ class CONTENT_EXPORT GpuDataManagerImpl // GpuDataManager implementation. virtual void InitializeForTesting( const std::string& gpu_blacklist_json, - const GPUInfo& gpu_info) OVERRIDE; + const gpu::GPUInfo& gpu_info) OVERRIDE; virtual bool IsFeatureBlacklisted(int feature) const OVERRIDE; - virtual GPUInfo GetGPUInfo() const OVERRIDE; + virtual gpu::GPUInfo GetGPUInfo() const OVERRIDE; virtual void GetGpuProcessHandles( const GetGpuProcessHandlesCallback& callback) const OVERRIDE; virtual bool GpuAccessAllowed(std::string* reason) const OVERRIDE; @@ -88,7 +88,7 @@ class CONTENT_EXPORT GpuDataManagerImpl // Only update if the current GPUInfo is not finalized. If blacklist is // loaded, run through blacklist and update blacklisted features. - void UpdateGpuInfo(const GPUInfo& gpu_info); + void UpdateGpuInfo(const gpu::GPUInfo& gpu_info); void UpdateVideoMemoryUsageStats( const GPUVideoMemoryUsageStats& video_memory_usage_stats); @@ -108,7 +108,7 @@ class CONTENT_EXPORT GpuDataManagerImpl // Update WebPreferences for renderer based on blacklisting decisions. void UpdateRendererWebPrefs(WebPreferences* prefs) const; - GpuSwitchingOption GetGpuSwitchingOption() const; + gpu::GpuSwitchingOption GetGpuSwitchingOption() const; std::string GetBlacklistVersion() const; diff --git a/content/browser/gpu/gpu_data_manager_impl_private.cc b/content/browser/gpu/gpu_data_manager_impl_private.cc index 2d9f36046c..fbc776cb9b 100644 --- a/content/browser/gpu/gpu_data_manager_impl_private.cc +++ b/content/browser/gpu/gpu_data_manager_impl_private.cc @@ -4,10 +4,6 @@ #include "content/browser/gpu/gpu_data_manager_impl_private.h" -#if defined(OS_MACOSX) -#include <ApplicationServices/ApplicationServices.h> -#endif // OS_MACOSX - #include "base/bind.h" #include "base/bind_helpers.h" #include "base/command_line.h" @@ -16,21 +12,21 @@ #include "base/metrics/histogram.h" #include "base/stringprintf.h" #include "base/strings/string_number_conversions.h" -#include "base/strings/string_piece.h" #include "base/sys_info.h" #include "base/version.h" +#include "cc/base/switches.h" #include "content/browser/gpu/gpu_process_host.h" -#include "content/browser/gpu/gpu_util.h" #include "content/common/gpu/gpu_messages.h" -#include "content/gpu/gpu_info_collector.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/gpu_data_manager_observer.h" #include "content/public/common/content_client.h" #include "content/public/common/content_constants.h" #include "content/public/common/content_switches.h" -#include "content/public/common/gpu_feature_type.h" #include "gpu/command_buffer/service/gpu_switches.h" -#include "grit/content_resources.h" +#include "gpu/config/gpu_control_list_jsons.h" +#include "gpu/config/gpu_feature_type.h" +#include "gpu/config/gpu_info_collector.h" +#include "gpu/config/gpu_util.h" #include "ui/base/ui_base_switches.h" #include "ui/gl/gl_implementation.h" #include "ui/gl/gl_switches.h" @@ -38,13 +34,157 @@ #include "webkit/glue/webpreferences.h" #include "webkit/plugins/plugin_switches.h" +#if defined(OS_MACOSX) +#include <ApplicationServices/ApplicationServices.h> +#endif // OS_MACOSX #if defined(OS_WIN) #include "base/win/windows_version.h" -#endif +#endif // OS_WIN +#if defined(OS_ANDROID) +#include "ui/gfx/android/device_display_info.h" +#endif // OS_ANDROID namespace content { + namespace { +enum GpuFeatureStatus { + kGpuFeatureEnabled = 0, + kGpuFeatureBlacklisted = 1, + kGpuFeatureDisabled = 2, // disabled by user but not blacklisted + kGpuFeatureNumStatus +}; + +#if defined(OS_WIN) + +enum WinSubVersion { + kWinOthers = 0, + kWinXP, + kWinVista, + kWin7, + kNumWinSubVersions +}; + +int GetGpuBlacklistHistogramValueWin(GpuFeatureStatus status) { + static WinSubVersion sub_version = kNumWinSubVersions; + if (sub_version == kNumWinSubVersions) { + sub_version = kWinOthers; + std::string version_str = base::SysInfo::OperatingSystemVersion(); + size_t pos = version_str.find_first_not_of("0123456789."); + if (pos != std::string::npos) + version_str = version_str.substr(0, pos); + Version os_version(version_str); + if (os_version.IsValid() && os_version.components().size() >= 2) { + const std::vector<uint16>& version_numbers = os_version.components(); + if (version_numbers[0] == 5) + sub_version = kWinXP; + else if (version_numbers[0] == 6 && version_numbers[1] == 0) + sub_version = kWinVista; + else if (version_numbers[0] == 6 && version_numbers[1] == 1) + sub_version = kWin7; + } + } + int entry_index = static_cast<int>(sub_version) * kGpuFeatureNumStatus; + switch (status) { + case kGpuFeatureEnabled: + break; + case kGpuFeatureBlacklisted: + entry_index++; + break; + case kGpuFeatureDisabled: + entry_index += 2; + break; + } + return entry_index; +} +#endif // OS_WIN + +// Send UMA histograms about the enabled features. +void UpdateStats(const gpu::GpuBlacklist* blacklist, + const std::set<int>& blacklisted_features) { + uint32 max_entry_id = blacklist->max_entry_id(); + if (max_entry_id == 0) { + // GPU Blacklist was not loaded. No need to go further. + return; + } + + const CommandLine& command_line = *CommandLine::ForCurrentProcess(); + bool disabled = false; + if (blacklisted_features.size() == 0) { + UMA_HISTOGRAM_ENUMERATION("GPU.BlacklistTestResultsPerEntry", + 0, max_entry_id + 1); + } else { + std::vector<uint32> flag_entries; + blacklist->GetDecisionEntries(&flag_entries, disabled); + DCHECK_GT(flag_entries.size(), 0u); + for (size_t i = 0; i < flag_entries.size(); ++i) { + UMA_HISTOGRAM_ENUMERATION("GPU.BlacklistTestResultsPerEntry", + flag_entries[i], max_entry_id + 1); + } + } + + // This counts how many users are affected by a disabled entry - this allows + // us to understand the impact of an entry before enable it. + std::vector<uint32> flag_disabled_entries; + disabled = true; + blacklist->GetDecisionEntries(&flag_disabled_entries, disabled); + for (size_t i = 0; i < flag_disabled_entries.size(); ++i) { + UMA_HISTOGRAM_ENUMERATION("GPU.BlacklistTestResultsPerDisabledEntry", + flag_disabled_entries[i], max_entry_id + 1); + } + + const gpu::GpuFeatureType kGpuFeatures[] = { + gpu::GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS, + gpu::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING, + gpu::GPU_FEATURE_TYPE_WEBGL + }; + const std::string kGpuBlacklistFeatureHistogramNames[] = { + "GPU.BlacklistFeatureTestResults.Accelerated2dCanvas", + "GPU.BlacklistFeatureTestResults.AcceleratedCompositing", + "GPU.BlacklistFeatureTestResults.Webgl" + }; + const bool kGpuFeatureUserFlags[] = { + command_line.HasSwitch(switches::kDisableAccelerated2dCanvas), + command_line.HasSwitch(switches::kDisableAcceleratedCompositing), +#if defined(OS_ANDROID) + !command_line.HasSwitch(switches::kEnableExperimentalWebGL) +#else + command_line.HasSwitch(switches::kDisableExperimentalWebGL) +#endif + }; +#if defined(OS_WIN) + const std::string kGpuBlacklistFeatureHistogramNamesWin[] = { + "GPU.BlacklistFeatureTestResultsWindows.Accelerated2dCanvas", + "GPU.BlacklistFeatureTestResultsWindows.AcceleratedCompositing", + "GPU.BlacklistFeatureTestResultsWindows.Webgl" + }; +#endif + const size_t kNumFeatures = + sizeof(kGpuFeatures) / sizeof(gpu::GpuFeatureType); + for (size_t i = 0; i < kNumFeatures; ++i) { + // We can't use UMA_HISTOGRAM_ENUMERATION here because the same name is + // expected if the macro is used within a loop. + GpuFeatureStatus value = kGpuFeatureEnabled; + if (blacklisted_features.count(kGpuFeatures[i])) + value = kGpuFeatureBlacklisted; + else if (kGpuFeatureUserFlags[i]) + value = kGpuFeatureDisabled; + base::HistogramBase* histogram_pointer = base::LinearHistogram::FactoryGet( + kGpuBlacklistFeatureHistogramNames[i], + 1, kGpuFeatureNumStatus, kGpuFeatureNumStatus + 1, + base::HistogramBase::kUmaTargetedHistogramFlag); + histogram_pointer->Add(value); +#if defined(OS_WIN) + histogram_pointer = base::LinearHistogram::FactoryGet( + kGpuBlacklistFeatureHistogramNamesWin[i], + 1, kNumWinSubVersions * kGpuFeatureNumStatus, + kNumWinSubVersions * kGpuFeatureNumStatus + 1, + base::HistogramBase::kUmaTargetedHistogramFlag); + histogram_pointer->Add(GetGpuBlacklistHistogramValueWin(value)); +#endif + } +} + // Strip out the non-digital info; if after that, we get an empty string, // return "0". std::string ProcessVersionString(const std::string& raw_string) { @@ -85,6 +225,81 @@ void DisplayReconfigCallback(CGDirectDisplayID display, } #endif // OS_MACOSX +#if defined(OS_ANDROID) +void ApplyAndroidWorkarounds(const gpu::GPUInfo& gpu_info, + CommandLine* command_line) { + std::string vendor(StringToLowerASCII(gpu_info.gl_vendor)); + std::string renderer(StringToLowerASCII(gpu_info.gl_renderer)); + bool is_img = + gpu_info.gl_vendor.find("Imagination") != std::string::npos; + bool is_arm = + gpu_info.gl_vendor.find("ARM") != std::string::npos; + bool is_qualcomm = + gpu_info.gl_vendor.find("Qualcomm") != std::string::npos; + bool is_broadcom = + gpu_info.gl_vendor.find("Broadcom") != std::string::npos; + bool is_mali_t604 = is_arm && + gpu_info.gl_renderer.find("Mali-T604") != std::string::npos; + + bool is_vivante = + gpu_info.gl_extensions.find("GL_VIV_shader_binary") != + std::string::npos; + + bool is_nexus7 = + gpu_info.machine_model.find("Nexus 7") != std::string::npos; + bool is_nexus10 = + gpu_info.machine_model.find("Nexus 10") != std::string::npos; + + // IMG: avoid context switching perf problems, crashes with share groups + // Mali-T604: http://crbug.com/154715 + // QualComm, NVIDIA: Crashes with share groups + if (is_vivante || is_img || is_mali_t604 || is_nexus7 || is_qualcomm || + is_broadcom) + command_line->AppendSwitch(switches::kEnableVirtualGLContexts); + + gfx::DeviceDisplayInfo info; + int default_tile_size = 256; + + // For very high resolution displays (eg. Nexus 10), set the default + // tile size to be 512. This should be removed in favour of a generic + // hueristic that works across all platforms and devices, once that + // exists: http://crbug.com/159524. This switches to 512 for screens + // containing 40 or more 256x256 tiles, such that 1080p devices do + // not use 512x512 tiles (eg. 1920x1280 requires 37.5 tiles) + int numTiles = (info.GetDisplayWidth() * + info.GetDisplayHeight()) / (256 * 256); + if (numTiles >= 40) + default_tile_size = 512; + + // IMG: Fast async texture uploads only work with non-power-of-two, + // but still multiple-of-eight sizes. + // http://crbug.com/168099 + if (is_img) + default_tile_size -= 8; + + // Set the command line if it isn't already set and we changed + // the default tile size. + if (default_tile_size != 256 && + !command_line->HasSwitch(switches::kDefaultTileWidth) && + !command_line->HasSwitch(switches::kDefaultTileHeight)) { + std::stringstream size; + size << default_tile_size; + command_line->AppendSwitchASCII( + switches::kDefaultTileWidth, size.str()); + command_line->AppendSwitchASCII( + switches::kDefaultTileHeight, size.str()); + } + + // Increase the resolution of low resolution tiles for Nexus tablets. + if ((is_nexus7 || is_nexus10) && + !command_line->HasSwitch( + cc::switches::kLowResolutionContentsScaleFactor)) { + command_line->AppendSwitchASCII( + cc::switches::kLowResolutionContentsScaleFactor, "0.25"); + } +} +#endif // OS_ANDROID + // Block all domains' use of 3D APIs for this many milliseconds if // approaching a threshold where system stability might be compromised. const int64 kBlockAllDomainsMs = 10000; @@ -102,7 +317,7 @@ enum BlockStatusHistogram { void GpuDataManagerImplPrivate::InitializeForTesting( const std::string& gpu_blacklist_json, - const GPUInfo& gpu_info) { + const gpu::GPUInfo& gpu_info) { // This function is for testing only, so disable histograms. update_histograms_ = false; @@ -113,7 +328,7 @@ bool GpuDataManagerImplPrivate::IsFeatureBlacklisted(int feature) const { if (use_swiftshader_) { // Skia's software rendering is probably more efficient than going through // software emulation of the GPU, so use that. - if (feature == GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS) + if (feature == gpu::GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS) return true; return false; } @@ -127,7 +342,7 @@ size_t GpuDataManagerImplPrivate::GetBlacklistedFeatureCount() const { return blacklisted_features_.size(); } -GPUInfo GpuDataManagerImplPrivate::GetGPUInfo() const { +gpu::GPUInfo GpuDataManagerImplPrivate::GetGPUInfo() const { return gpu_info_; } @@ -164,7 +379,7 @@ bool GpuDataManagerImplPrivate::GpuAccessAllowed( // than those in the preliminary gpu feature flags because the latter work // through renderer commandline switches. std::set<int> features = preliminary_blacklisted_features_; - MergeFeatureSets(&features, blacklisted_features_); + gpu::MergeFeatureSets(&features, blacklisted_features_); if (features.size() > preliminary_blacklisted_features_.size()) { if (reason) { *reason = "Features are disabled upon full but not preliminary GPU info."; @@ -172,7 +387,7 @@ bool GpuDataManagerImplPrivate::GpuAccessAllowed( return false; } - if (blacklisted_features_.size() == NUMBER_OF_GPU_FEATURE_TYPES) { + if (blacklisted_features_.size() == gpu::NUMBER_OF_GPU_FEATURE_TYPES) { // On Linux, we use cached GL strings to make blacklist decsions at browser // startup time. We need to launch the GPU process to validate these // strings even if all features are blacklisted. If all GPU features are @@ -275,13 +490,13 @@ void GpuDataManagerImplPrivate::SetGLStrings(const std::string& gl_vendor, !gpu_info_.gl_version_string.empty()) return; - GPUInfo gpu_info = gpu_info_; + gpu::GPUInfo gpu_info = gpu_info_; gpu_info.gl_vendor = gl_vendor; gpu_info.gl_renderer = gl_renderer; gpu_info.gl_version_string = gl_version; - gpu_info_collector::CollectDriverInfoGL(&gpu_info); + gpu::CollectDriverInfoGL(&gpu_info); UpdateGpuInfo(gpu_info); UpdateGpuSwitchingManager(gpu_info); @@ -304,11 +519,11 @@ void GpuDataManagerImplPrivate::Initialize() { if (command_line->HasSwitch(switches::kSkipGpuDataLoading)) return; - GPUInfo gpu_info; + gpu::GPUInfo gpu_info; { TRACE_EVENT0("startup", "GpuDataManagerImpl::Initialize:CollectBasicGraphicsInfo"); - gpu_info_collector::CollectBasicGraphicsInfo(&gpu_info); + gpu::CollectBasicGraphicsInfo(&gpu_info); } #if defined(ARCH_CPU_X86_FAMILY) if (!gpu_info.gpu.vendor_id || !gpu_info.gpu.device_id) @@ -319,43 +534,24 @@ void GpuDataManagerImplPrivate::Initialize() { std::string gpu_switching_list_string; std::string gpu_driver_bug_list_string; if (!command_line->HasSwitch(switches::kIgnoreGpuBlacklist)) { - const base::StringPiece gpu_blacklist_json = - GetContentClient()->GetDataResource( - IDR_GPU_BLACKLIST, ui::SCALE_FACTOR_NONE); - gpu_blacklist_string = gpu_blacklist_json.as_string(); - const base::StringPiece gpu_switching_list_json = - GetContentClient()->GetDataResource( - IDR_GPU_SWITCHING_LIST, ui::SCALE_FACTOR_NONE); - gpu_switching_list_string = gpu_switching_list_json.as_string(); + gpu_blacklist_string = gpu::kSoftwareRenderingListJson; + gpu_switching_list_string = gpu::kGpuSwitchingListJson; } if (!command_line->HasSwitch(switches::kDisableGpuDriverBugWorkarounds)) { - const base::StringPiece gpu_driver_bug_list_json = - GetContentClient()->GetDataResource( - IDR_GPU_DRIVER_BUG_LIST, ui::SCALE_FACTOR_NONE); - gpu_driver_bug_list_string = gpu_driver_bug_list_json.as_string(); + gpu_driver_bug_list_string = gpu::kGpuDriverBugListJson; } InitializeImpl(gpu_blacklist_string, gpu_switching_list_string, gpu_driver_bug_list_string, gpu_info); - // We pass down the list to GPU command buffer through commandline - // switches at GPU process launch. However, in situations where we don't - // have a GPU process, we append the browser process commandline. - if (command_line->HasSwitch(switches::kSingleProcess) || - command_line->HasSwitch(switches::kInProcessGPU)) { - if (!gpu_driver_bugs_.empty()) { - command_line->AppendSwitchASCII(switches::kGpuDriverBugWorkarounds, - IntSetToString(gpu_driver_bugs_)); - } - } } -void GpuDataManagerImplPrivate::UpdateGpuInfo(const GPUInfo& gpu_info) { +void GpuDataManagerImplPrivate::UpdateGpuInfo(const gpu::GPUInfo& gpu_info) { // No further update of gpu_info if falling back to SwiftShader. if (use_swiftshader_) return; - gpu_info_collector::MergeGPUInfo(&gpu_info_, gpu_info); + gpu::MergeGPUInfo(&gpu_info_, gpu_info); complete_gpu_info_already_requested_ = complete_gpu_info_already_requested_ || gpu_info_.finalized; @@ -363,7 +559,7 @@ void GpuDataManagerImplPrivate::UpdateGpuInfo(const GPUInfo& gpu_info) { if (gpu_blacklist_) { std::set<int> features = gpu_blacklist_->MakeDecision( - GpuControlList::kOsAny, std::string(), gpu_info_); + gpu::GpuControlList::kOsAny, std::string(), gpu_info_); if (update_histograms_) UpdateStats(gpu_blacklist_.get(), features); @@ -371,17 +567,20 @@ void GpuDataManagerImplPrivate::UpdateGpuInfo(const GPUInfo& gpu_info) { } if (gpu_switching_list_) { std::set<int> option = gpu_switching_list_->MakeDecision( - GpuControlList::kOsAny, std::string(), gpu_info_); + gpu::GpuControlList::kOsAny, std::string(), gpu_info_); if (option.size() == 1) { // Blacklist decision should not overwrite commandline switch from users. CommandLine* command_line = CommandLine::ForCurrentProcess(); - if (!command_line->HasSwitch(switches::kGpuSwitching)) - gpu_switching_ = static_cast<GpuSwitchingOption>(*(option.begin())); + if (!command_line->HasSwitch(switches::kGpuSwitching)) { + gpu_switching_ = static_cast<gpu::GpuSwitchingOption>( + *(option.begin())); + } } } - if (gpu_driver_bug_list_) + if (gpu_driver_bug_list_) { gpu_driver_bugs_ = gpu_driver_bug_list_->MakeDecision( - GpuControlList::kOsAny, std::string(), gpu_info_); + gpu::GpuControlList::kOsAny, std::string(), gpu_info_); + } // We have to update GpuFeatureType before notify all the observers. NotifyGpuInfoUpdate(); @@ -398,7 +597,7 @@ void GpuDataManagerImplPrivate::AppendRendererCommandLine( CommandLine* command_line) const { DCHECK(command_line); - if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_WEBGL)) { + if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_WEBGL)) { #if !defined(OS_ANDROID) if (!command_line->HasSwitch(switches::kDisableExperimentalWebGL)) command_line->AppendSwitch(switches::kDisableExperimentalWebGL); @@ -406,16 +605,16 @@ void GpuDataManagerImplPrivate::AppendRendererCommandLine( if (!command_line->HasSwitch(switches::kDisablePepper3d)) command_line->AppendSwitch(switches::kDisablePepper3d); } - if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_MULTISAMPLING) && + if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_MULTISAMPLING) && !command_line->HasSwitch(switches::kDisableGLMultisampling)) command_line->AppendSwitch(switches::kDisableGLMultisampling); - if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING) && + if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING) && !command_line->HasSwitch(switches::kDisableAcceleratedCompositing)) command_line->AppendSwitch(switches::kDisableAcceleratedCompositing); - if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS) && + if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS) && !command_line->HasSwitch(switches::kDisableAccelerated2dCanvas)) command_line->AppendSwitch(switches::kDisableAccelerated2dCanvas); - if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE) && + if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE) && !command_line->HasSwitch(switches::kDisableAcceleratedVideoDecode)) command_line->AppendSwitch(switches::kDisableAcceleratedVideoDecode); if (ShouldUseSwiftShader()) @@ -431,19 +630,21 @@ void GpuDataManagerImplPrivate::AppendGpuCommandLine( base::FilePath swiftshader_path = CommandLine::ForCurrentProcess()->GetSwitchValuePath( switches::kSwiftShaderPath); - if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_MULTISAMPLING) && + if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_MULTISAMPLING) && !command_line->HasSwitch(switches::kDisableGLMultisampling)) command_line->AppendSwitch(switches::kDisableGLMultisampling); - if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_TEXTURE_SHARING)) + if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_TEXTURE_SHARING)) command_line->AppendSwitch(switches::kDisableImageTransportSurface); if (use_swiftshader_) { command_line->AppendSwitchASCII(switches::kUseGL, "swiftshader"); if (swiftshader_path.empty()) swiftshader_path = swiftshader_path_; - } else if ((IsFeatureBlacklisted(GPU_FEATURE_TYPE_WEBGL) || - IsFeatureBlacklisted(GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING) || - IsFeatureBlacklisted(GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS)) && + } else if ((IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_WEBGL) || + IsFeatureBlacklisted( + gpu::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING) || + IsFeatureBlacklisted( + gpu::GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS)) && (use_gl == "any")) { command_line->AppendSwitchASCII( switches::kUseGL, gfx::kGLImplementationOSMesaName); @@ -453,16 +654,16 @@ void GpuDataManagerImplPrivate::AppendGpuCommandLine( if (ui::GpuSwitchingManager::GetInstance()->SupportsDualGpus()) { command_line->AppendSwitchASCII(switches::kSupportsDualGpus, "true"); switch (gpu_switching_) { - case GPU_SWITCHING_OPTION_FORCE_DISCRETE: + case gpu::GPU_SWITCHING_OPTION_FORCE_DISCRETE: command_line->AppendSwitchASCII(switches::kGpuSwitching, switches::kGpuSwitchingOptionNameForceDiscrete); break; - case GPU_SWITCHING_OPTION_FORCE_INTEGRATED: + case gpu::GPU_SWITCHING_OPTION_FORCE_INTEGRATED: command_line->AppendSwitchASCII(switches::kGpuSwitching, switches::kGpuSwitchingOptionNameForceIntegrated); break; - case GPU_SWITCHING_OPTION_AUTOMATIC: - case GPU_SWITCHING_OPTION_UNKNOWN: + case gpu::GPU_SWITCHING_OPTION_AUTOMATIC: + case gpu::GPU_SWITCHING_OPTION_UNKNOWN: break; } } else { @@ -520,7 +721,7 @@ void GpuDataManagerImplPrivate::AppendPluginCommandLine( // TODO(jbauman): Add proper blacklist support for core animation plugins so // special-casing this video card won't be necessary. See // http://crbug.com/134015 - if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING) || + if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING) || CommandLine::ForCurrentProcess()->HasSwitch( switches::kDisableAcceleratedCompositing)) { if (!command_line->HasSwitch( @@ -535,27 +736,27 @@ void GpuDataManagerImplPrivate::UpdateRendererWebPrefs( WebPreferences* prefs) const { DCHECK(prefs); - if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING)) + if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING)) prefs->accelerated_compositing_enabled = false; - if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_WEBGL)) + if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_WEBGL)) prefs->experimental_webgl_enabled = false; - if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_FLASH3D)) + if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_FLASH3D)) prefs->flash_3d_enabled = false; - if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_FLASH_STAGE3D)) { + if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_FLASH_STAGE3D)) { prefs->flash_stage3d_enabled = false; prefs->flash_stage3d_baseline_enabled = false; } - if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_FLASH_STAGE3D_BASELINE)) + if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_FLASH_STAGE3D_BASELINE)) prefs->flash_stage3d_baseline_enabled = false; - if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS)) + if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS)) prefs->accelerated_2d_canvas_enabled = false; - if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_MULTISAMPLING)) + if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_MULTISAMPLING)) prefs->gl_multisampling_enabled = false; - if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_3D_CSS)) { + if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_3D_CSS)) { prefs->accelerated_compositing_for_3d_transforms_enabled = false; prefs->accelerated_compositing_for_animation_enabled = false; } - if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_ACCELERATED_VIDEO)) + if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO)) prefs->accelerated_compositing_for_video_enabled = false; // Accelerated video and animation are slower than regular when using @@ -568,16 +769,17 @@ void GpuDataManagerImplPrivate::UpdateRendererWebPrefs( } } -GpuSwitchingOption GpuDataManagerImplPrivate::GetGpuSwitchingOption() const { +gpu::GpuSwitchingOption +GpuDataManagerImplPrivate::GetGpuSwitchingOption() const { if (!ui::GpuSwitchingManager::GetInstance()->SupportsDualGpus()) - return GPU_SWITCHING_OPTION_UNKNOWN; + return gpu::GPU_SWITCHING_OPTION_UNKNOWN; return gpu_switching_; } void GpuDataManagerImplPrivate::DisableHardwareAcceleration() { card_blacklisted_ = true; - for (int i = 0; i < NUMBER_OF_GPU_FEATURE_TYPES; ++i) + for (int i = 0; i < gpu::NUMBER_OF_GPU_FEATURE_TYPES; ++i) blacklisted_features_.insert(i); EnableSwiftShaderIfNecessary(); @@ -649,7 +851,7 @@ bool GpuDataManagerImplPrivate::IsUsingAcceleratedSurface() const { CommandLine* command_line = CommandLine::ForCurrentProcess(); if (command_line->HasSwitch(switches::kDisableImageTransportSurface)) return false; - return !IsFeatureBlacklisted(GPU_FEATURE_TYPE_TEXTURE_SHARING); + return !IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_TEXTURE_SHARING); } #endif @@ -690,7 +892,7 @@ GpuDataManagerImplPrivate* GpuDataManagerImplPrivate::Create( GpuDataManagerImplPrivate::GpuDataManagerImplPrivate( GpuDataManagerImpl* owner) : complete_gpu_info_already_requested_(false), - gpu_switching_(GPU_SWITCHING_OPTION_AUTOMATIC), + gpu_switching_(gpu::GPU_SWITCHING_OPTION_AUTOMATIC), observer_list_(new GpuDataManagerObserverList), use_swiftshader_(false), card_blacklisted_(false), @@ -709,8 +911,9 @@ GpuDataManagerImplPrivate::GpuDataManagerImplPrivate( if (command_line->HasSwitch(switches::kGpuSwitching)) { std::string option_string = command_line->GetSwitchValueASCII( switches::kGpuSwitching); - GpuSwitchingOption option = StringToGpuSwitchingOption(option_string); - if (option != GPU_SWITCHING_OPTION_UNKNOWN) + gpu::GpuSwitchingOption option = + gpu::StringToGpuSwitchingOption(option_string); + if (option != gpu::GPU_SWITCHING_OPTION_UNKNOWN) gpu_switching_ = option; } @@ -729,34 +932,49 @@ void GpuDataManagerImplPrivate::InitializeImpl( const std::string& gpu_blacklist_json, const std::string& gpu_switching_list_json, const std::string& gpu_driver_bug_list_json, - const GPUInfo& gpu_info) { + const gpu::GPUInfo& gpu_info) { std::string browser_version_string = ProcessVersionString( GetContentClient()->GetProduct()); CHECK(!browser_version_string.empty()); if (!gpu_blacklist_json.empty()) { - gpu_blacklist_.reset(GpuBlacklist::Create()); + gpu_blacklist_.reset(gpu::GpuBlacklist::Create()); gpu_blacklist_->LoadList( browser_version_string, gpu_blacklist_json, - GpuControlList::kCurrentOsOnly); + gpu::GpuControlList::kCurrentOsOnly); } if (!gpu_switching_list_json.empty()) { - gpu_switching_list_.reset(GpuSwitchingList::Create()); + gpu_switching_list_.reset(gpu::GpuSwitchingList::Create()); gpu_switching_list_->LoadList( browser_version_string, gpu_switching_list_json, - GpuControlList::kCurrentOsOnly); + gpu::GpuControlList::kCurrentOsOnly); } if (!gpu_driver_bug_list_json.empty()) { - gpu_driver_bug_list_.reset(GpuDriverBugList::Create()); + gpu_driver_bug_list_.reset(gpu::GpuDriverBugList::Create()); gpu_driver_bug_list_->LoadList( browser_version_string, gpu_driver_bug_list_json, - GpuControlList::kCurrentOsOnly); + gpu::GpuControlList::kCurrentOsOnly); } gpu_info_ = gpu_info; UpdateGpuInfo(gpu_info); UpdateGpuSwitchingManager(gpu_info); UpdatePreliminaryBlacklistedFeatures(); + + CommandLine* command_line = CommandLine::ForCurrentProcess(); + // We pass down the list to GPU command buffer through commandline + // switches at GPU process launch. However, in situations where we don't + // have a GPU process, we append the browser process commandline. + if (command_line->HasSwitch(switches::kSingleProcess) || + command_line->HasSwitch(switches::kInProcessGPU)) { + if (!gpu_driver_bugs_.empty()) { + command_line->AppendSwitchASCII(switches::kGpuDriverBugWorkarounds, + IntSetToString(gpu_driver_bugs_)); + } + } +#if defined(OS_ANDROID) + ApplyAndroidWorkarounds(gpu_info, command_line); +#endif // OS_ANDROID } void GpuDataManagerImplPrivate::UpdateBlacklistedFeatures( @@ -768,11 +986,12 @@ void GpuDataManagerImplPrivate::UpdateBlacklistedFeatures( // otherwise be allowed. if (card_blacklisted_ || command_line->HasSwitch(switches::kBlacklistAcceleratedCompositing)) { - blacklisted_features_.insert(GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING); + blacklisted_features_.insert( + gpu::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING); } if (card_blacklisted_ || command_line->HasSwitch(switches::kBlacklistWebGL)) { - blacklisted_features_.insert(GPU_FEATURE_TYPE_WEBGL); + blacklisted_features_.insert(gpu::GPU_FEATURE_TYPE_WEBGL); } EnableSwiftShaderIfNecessary(); @@ -783,20 +1002,20 @@ void GpuDataManagerImplPrivate::UpdatePreliminaryBlacklistedFeatures() { } void GpuDataManagerImplPrivate::UpdateGpuSwitchingManager( - const GPUInfo& gpu_info) { + const gpu::GPUInfo& gpu_info) { ui::GpuSwitchingManager::GetInstance()->SetGpuCount( gpu_info.secondary_gpus.size() + 1); if (ui::GpuSwitchingManager::GetInstance()->SupportsDualGpus()) { switch (gpu_switching_) { - case GPU_SWITCHING_OPTION_FORCE_DISCRETE: + case gpu::GPU_SWITCHING_OPTION_FORCE_DISCRETE: ui::GpuSwitchingManager::GetInstance()->ForceUseOfDiscreteGpu(); break; - case GPU_SWITCHING_OPTION_FORCE_INTEGRATED: + case gpu::GPU_SWITCHING_OPTION_FORCE_INTEGRATED: ui::GpuSwitchingManager::GetInstance()->ForceUseOfIntegratedGpu(); break; - case GPU_SWITCHING_OPTION_AUTOMATIC: - case GPU_SWITCHING_OPTION_UNKNOWN: + case gpu::GPU_SWITCHING_OPTION_AUTOMATIC: + case gpu::GPU_SWITCHING_OPTION_UNKNOWN: break; } } @@ -808,7 +1027,7 @@ void GpuDataManagerImplPrivate::NotifyGpuInfoUpdate() { void GpuDataManagerImplPrivate::EnableSwiftShaderIfNecessary() { if (!GpuAccessAllowed(NULL) || - blacklisted_features_.count(GPU_FEATURE_TYPE_WEBGL)) { + blacklisted_features_.count(gpu::GPU_FEATURE_TYPE_WEBGL)) { if (!swiftshader_path_.empty() && !CommandLine::ForCurrentProcess()->HasSwitch( switches::kDisableSoftwareRasterizer)) diff --git a/content/browser/gpu/gpu_data_manager_impl_private.h b/content/browser/gpu/gpu_data_manager_impl_private.h index fb91a465cd..9b01af5752 100644 --- a/content/browser/gpu/gpu_data_manager_impl_private.h +++ b/content/browser/gpu/gpu_data_manager_impl_private.h @@ -13,10 +13,10 @@ #include "base/memory/ref_counted.h" #include "base/memory/singleton.h" #include "base/observer_list_threadsafe.h" -#include "content/browser/gpu/gpu_blacklist.h" #include "content/browser/gpu/gpu_data_manager_impl.h" -#include "content/browser/gpu/gpu_driver_bug_list.h" -#include "content/browser/gpu/gpu_switching_list.h" +#include "gpu/config/gpu_blacklist.h" +#include "gpu/config/gpu_driver_bug_list.h" +#include "gpu/config/gpu_switching_list.h" namespace content { @@ -26,9 +26,9 @@ class CONTENT_EXPORT GpuDataManagerImplPrivate { void InitializeForTesting( const std::string& gpu_blacklist_json, - const GPUInfo& gpu_info); + const gpu::GPUInfo& gpu_info); bool IsFeatureBlacklisted(int feature) const; - GPUInfo GetGPUInfo() const; + gpu::GPUInfo GetGPUInfo() const; void GetGpuProcessHandles( const GpuDataManager::GetGpuProcessHandlesCallback& callback) const; bool GpuAccessAllowed(std::string* reason) const; @@ -51,7 +51,7 @@ class CONTENT_EXPORT GpuDataManagerImplPrivate { void Initialize(); - void UpdateGpuInfo(const GPUInfo& gpu_info); + void UpdateGpuInfo(const gpu::GPUInfo& gpu_info); void UpdateVideoMemoryUsageStats( const GPUVideoMemoryUsageStats& video_memory_usage_stats); @@ -64,7 +64,7 @@ class CONTENT_EXPORT GpuDataManagerImplPrivate { void UpdateRendererWebPrefs(WebPreferences* prefs) const; - GpuSwitchingOption GetGpuSwitchingOption() const; + gpu::GpuSwitchingOption GetGpuSwitchingOption() const; std::string GetBlacklistVersion() const; @@ -160,7 +160,7 @@ class CONTENT_EXPORT GpuDataManagerImplPrivate { void InitializeImpl(const std::string& gpu_blacklist_json, const std::string& gpu_switching_list_json, const std::string& gpu_driver_bug_list_json, - const GPUInfo& gpu_info); + const gpu::GPUInfo& gpu_info); void UpdateBlacklistedFeatures(const std::set<int>& features); @@ -170,7 +170,7 @@ class CONTENT_EXPORT GpuDataManagerImplPrivate { // Update the GPU switching status. // This should only be called once at initialization time. - void UpdateGpuSwitchingManager(const GPUInfo& gpu_info); + void UpdateGpuSwitchingManager(const gpu::GPUInfo& gpu_info); // Notify all observers whenever there is a GPU info update. void NotifyGpuInfoUpdate(); @@ -195,15 +195,15 @@ class CONTENT_EXPORT GpuDataManagerImplPrivate { std::set<int> blacklisted_features_; std::set<int> preliminary_blacklisted_features_; - GpuSwitchingOption gpu_switching_; + gpu::GpuSwitchingOption gpu_switching_; std::set<int> gpu_driver_bugs_; - GPUInfo gpu_info_; + gpu::GPUInfo gpu_info_; - scoped_ptr<GpuBlacklist> gpu_blacklist_; - scoped_ptr<GpuSwitchingList> gpu_switching_list_; - scoped_ptr<GpuDriverBugList> gpu_driver_bug_list_; + scoped_ptr<gpu::GpuBlacklist> gpu_blacklist_; + scoped_ptr<gpu::GpuSwitchingList> gpu_switching_list_; + scoped_ptr<gpu::GpuDriverBugList> gpu_driver_bug_list_; const scoped_refptr<GpuDataManagerObserverList> observer_list_; diff --git a/content/browser/gpu/gpu_driver_bug_list.cc b/content/browser/gpu/gpu_driver_bug_list.cc deleted file mode 100644 index 9ab93f2343..0000000000 --- a/content/browser/gpu/gpu_driver_bug_list.cc +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/browser/gpu/gpu_driver_bug_list.h" - -#include "base/basictypes.h" -#include "base/logging.h" -#include "gpu/command_buffer/service/gpu_driver_bug_workaround_type.h" - -namespace content { - -namespace { - -struct DriverBugInfo { - int feature_type; - std::string feature_name; -}; - -} // namespace anonymous - -GpuDriverBugList::GpuDriverBugList() - : GpuControlList() { -} - -GpuDriverBugList::~GpuDriverBugList() { -} - -// static -GpuDriverBugList* GpuDriverBugList::Create() { - GpuDriverBugList* list = new GpuDriverBugList(); - - const DriverBugInfo kFeatureList[] = { -#define GPU_OP(type, name) { gpu::type, #name }, - GPU_DRIVER_BUG_WORKAROUNDS(GPU_OP) -#undef GPU_OP - }; - DCHECK_EQ(static_cast<int>(arraysize(kFeatureList)), - gpu::NUMBER_OF_GPU_DRIVER_BUG_WORKAROUND_TYPES); - for (int i = 0; i < gpu::NUMBER_OF_GPU_DRIVER_BUG_WORKAROUND_TYPES; ++i) { - list->AddSupportedFeature(kFeatureList[i].feature_name, - kFeatureList[i].feature_type); - } - return list; -} - -} // namespace content - diff --git a/content/browser/gpu/gpu_driver_bug_list.h b/content/browser/gpu/gpu_driver_bug_list.h deleted file mode 100644 index 06d2e275e0..0000000000 --- a/content/browser/gpu/gpu_driver_bug_list.h +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_BROWSER_GPU_GPU_DRIVER_BUG_LIST_H_ -#define CONTENT_BROWSER_GPU_GPU_DRIVER_BUG_LIST_H_ - -#include <string> - -#include "content/browser/gpu/gpu_control_list.h" - -namespace content { - -class CONTENT_EXPORT GpuDriverBugList : public GpuControlList { - public: - virtual ~GpuDriverBugList(); - - static GpuDriverBugList* Create(); - - private: - GpuDriverBugList(); - - DISALLOW_COPY_AND_ASSIGN(GpuDriverBugList); -}; - -} // namespace content - -#endif // CONTENT_BROWSER_GPU_GPU_DRIVER_BUG_LIST_H_ - diff --git a/content/browser/gpu/gpu_driver_bug_list.json b/content/browser/gpu/gpu_driver_bug_list.json deleted file mode 100644 index 29528a2573..0000000000 --- a/content/browser/gpu/gpu_driver_bug_list.json +++ /dev/null @@ -1,336 +0,0 @@ -// Determines whether a certain driver bug exists in the current system. -// A valid gpu_driver_bug_list.json file are in the format of -// { -// "version": "x.y", -// "entries": [ -// { // entry 1 -// }, -// ... -// { // entry n -// } -// ] -// } -// -// Each entry contains the following fields (fields are optional unless -// specifically described as mandatory below): -// 1. "id" is an integer. 0 is reserved. This field is mandatory. -// 2. "os" contains "type" and an optional "version". "type" could be "macosx", -// "linux", "win", "chromeos", or "any". "any" is the same as not specifying -// "os". -// "version" is a VERSION structure (defined below). -// 3. "vendor_id" is a string. 0 is reserved. -// 4. "device_id" is an array of strings. 0 is reserved. -// 5. "multi_gpu_style" is a string, valid values include "optimus", and -// "amd_switchable". -// 6. "multi_gpu_category" is a string, valid values include "any", "primary", -// and "secondary". If unspecified, the default value is "primary". -// 7. "driver_vendor" is a STRING structure (defined below). -// 8. "driver_version" is a VERSION structure (defined below). -// 9. "driver_date" is a VERSION structure (defined below). -// The version is interpreted as "year.month.day". -// 10. "gl_vendor" is a STRING structure (defined below). -// 11. "gl_renderer" is a STRING structure (defined below). -// 12. "gl_extensions" is a STRING structure (defined below). -// 13. "perf_graphics" is a FLOAT structure (defined below). -// 14. "perf_gaming" is a FLOAT structure (defined below). -// 15. "perf_overall" is a FLOAT structure (defined below). -// 16. "machine_model" contais "name" and an optional "version". "name" is a -// STRING structure and "version" is a VERSION structure (defined below). -// 17. "gpu_count" is a INT structure (defined below). -// 18 "cpu_info" is a STRING structure (defined below). -// 19. "exceptions" is a list of entries. -// 20. "features" is a list of driver bug types. For a list of supported types, -// see src/gpu/command_buffer/service/gpu_driver_bug_workaround_type.h -// This field is mandatory. -// 21. "description" has the description of the entry. -// 22. "webkit_bugs" is an array of associated webkit bug numbers. -// 23. "cr_bugs" is an array of associated chromium bug numbers. -// 24. "browser_version" is a VERSION structure (defined below). If this -// condition is not satisfied, the entry will be ignored. If it is not -// present, then the entry applies to all versions of the browser. -// 25. "disabled" is a boolean. If it is present, the entry will be skipped. -// This can not be used in exceptions. -// -// VERSION includes "op", "style", "number", and "number2". "op" can be any of -// the following values: "=", "<", "<=", ">", ">=", "any", "between". "style" -// is optional and can be "lexical" or "numerical"; if it's not specified, it -// defaults to "numerical". "number2" is only used if "op" is "between". -// "between" is "number <= * <= number2". -// "number" is used for all "op" values except "any". "number" and "number2" -// are in the format of x, x.x, x.x.x, etc. -// Only "driver_version" supports lexical style if the format is major.minor; -// in that case, major is still numerical, but minor is lexical. -// -// STRING includes "op" and "value". "op" can be any of the following values: -// "contains", "beginwith", "endwith", "=". "value" is a string. -// -// FLOAT includes "op" "value", and "value2". "op" can be any of the -// following values: "=", "<", "<=", ">", ">=", "any", "between". "value2" is -// only used if "op" is "between". "value" is used for all "op" values except -// "any". "value" and "value2" are valid float numbers. -// INT is very much like FLOAT, except that the values need to be integers. - -{ - "name": "gpu driver bug list", - // Please update the version number whenever you change this file. - "version": "1.4", - "entries": [ - { - "id": 1, - "description": "Imagination driver doesn't like uploading lots of buffer data constantly", - "os": { - "type": "android" - }, - "gl_vendor": { - "op": "beginwith", - "value": "Imagination" - }, - "features": [ - "use_client_side_arrays_for_stream_buffers" - ] - }, - { - "id": 2, - "description": "ARM driver doesn't like uploading lots of buffer data constantly", - "os": { - "type": "android" - }, - "gl_vendor": { - "op": "beginwith", - "value": "ARM" - }, - "features": [ - "use_client_side_arrays_for_stream_buffers" - ] - }, - { - "id": 3, - "features": [ - "set_texture_filter_before_generating_mipmap" - ] - }, - { - "id": 4, - "description": "Need to set the alpha to 255", - "features": [ - "clear_alpha_in_readpixels" - ] - }, - { - "id": 5, - "vendor_id": "0x10de", - "features": [ - "use_current_program_after_successful_link" - ] - }, - { - "id": 6, - "os": { - "type": "android" - }, - "gl_vendor": { - "op": "beginwith", - "value": "Qualcomm" - }, - "features": [ - "restore_scissor_on_fbo_change", - "flush_on_context_switch", - "delete_instead_of_resize_fbo" // Only need this on the ICS driver. - ] - }, - { - "id": 7, - "cr_bugs": [89557], - "os": { - "type": "macosx" - }, - "vendor_id": "0x10de", - "features": [ - "needs_offscreen_buffer_workaround" - ] - }, - { - "id": 8, - "os": { - "type": "macosx" - }, - "vendor_id": "0x1002", - "features": [ - "needs_glsl_built_in_function_emulation" - ] - }, - { - "id": 9, - "description": "Mac AMD drivers get gl_PointCoord backward, rdar://problem/11883495", - "os": { - "type": "macosx" - }, - "vendor_id": "0x1002", - "features": [ - "reverse_point_sprite_coord_origin" - ] - }, - { - "id": 10, - "description": "Mac Intel drivers get gl_PointCoord backward, rdar://problem/11883495", - "os": { - "type": "macosx" - }, - "vendor_id": "0x8086", - "features": [ - "reverse_point_sprite_coord_origin" - ] - }, - { - "id": 11, - "os": { - "type": "macosx" - }, - "vendor_id": "0x8086", - "features": [ - "max_texture_size_limit_4096" - ] - }, - { - "id": 12, - "os": { - "type": "macosx" - }, - "vendor_id": "0x8086", - "features": [ - "max_cube_map_texture_size_limit_1024" - ] - }, - { - "id": 13, - "os": { - "type": "macosx", - "version": { - "op": "<", - "number": "10.7.3" - } - }, - "vendor_id": "0x8086", - "features": [ - "max_cube_map_texture_size_limit_512" - ] - }, - { - "id": 14, - "os": { - "type": "macosx" - }, - "vendor_id": "0x1002", - "features": [ - "max_texture_size_limit_4096", - "max_cube_map_texture_size_limit_4096" - ] - }, - { - "id": 15, - "description": "Some Android Qualcomm drivers falsely report GL_ANGLE_framebuffer_multisample", - "cr_bugs": [165736], - "os": { - "type": "android" - }, - "gl_vendor": { - "op": "beginwith", - "value": "Qualcomm" - }, - "features": [ - "disable_angle_framebuffer_multisample" - ] - }, - { - "id": 16, - "description": "Intel drivers on Linux appear to be buggy", - "os": { - "type": "linux" - }, - "vendor_id": "0x8086", - "features": [ - "disable_ext_occlusion_query" - ] - }, - { - "id": 17, - "description": "Some drivers are unable to reset the D3D device in the GPU process sandbox", - "os": { - "type": "win" - }, - "features": [ - "exit_on_context_lost" - ] - }, - { - "id": 18, - "description": "Everything except async + NPOT + multiple-of-8 textures are brutally slow for Imagination drivers", - "os": { - "type": "android" - }, - "gl_vendor": { - "op": "beginwith", - "value": "Imagination" - }, - "features": [ - "enable_chromium_fast_npot_mo8_textures" - ] - }, - { - "id": 19, - "os": { - "type": "android" - }, - "gl_vendor": { - "op": "beginwith", - "value": "Qualcomm" - }, - "features": [ - "disable_depth_texture" - ] - }, - { - "id": 20, - "description": "Disable EXT_draw_buffers on GeForce GT 650M on Mac OS X due to driver bugs.", - "os": { - "type": "macosx" - }, - "vendor_id": "0x10de", - "device_id": ["0x0fd5"], - "multi_gpu_category": "any", - "features": [ - "disable_ext_draw_buffers" - ] - }, - { - "id": 21, - "description": "Vivante GPUs are buggy with context switching.", - "cr_bugs": [179250, 235935], - "os": { - "type": "android" - }, - "gl_extensions": { - "op": "contains", - "value": "GL_VIV_shader_binary" - }, - "features": [ - "unbind_fbo_on_context_switch" - ] - }, - { - "id": 22, - "description": "Imagination drivers are buggy with context switching.", - "cr_bugs": [230896], - "os": { - "type": "android" - }, - "gl_vendor": { - "op": "beginwith", - "value": "Imagination" - }, - "features": [ - "unbind_fbo_on_context_switch" - ] - } - ] -} diff --git a/content/browser/gpu/gpu_driver_bug_list_unittest.cc b/content/browser/gpu/gpu_driver_bug_list_unittest.cc deleted file mode 100644 index ff27d0e4c4..0000000000 --- a/content/browser/gpu/gpu_driver_bug_list_unittest.cc +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/base_paths.h" -#include "base/file_util.h" -#include "base/files/file_path.h" -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "base/path_service.h" -#include "content/browser/gpu/gpu_driver_bug_list.h" -#include "content/public/common/gpu_info.h" -#include "gpu/command_buffer/service/gpu_driver_bug_workaround_type.h" -#include "testing/gtest/include/gtest/gtest.h" - -const char kOsVersion[] = "10.6.4"; - -namespace content { - -class GpuDriverBugListTest : public testing::Test { - public: - GpuDriverBugListTest() { } - - virtual ~GpuDriverBugListTest() { } - - const GPUInfo& gpu_info() const { - return gpu_info_; - } - - bool GetCurrentDriverBugList(std::string* json) { - DCHECK(json); - base::FilePath data_file; - if (!PathService::Get(base::DIR_SOURCE_ROOT, &data_file)) - return false; - data_file = - data_file.Append(FILE_PATH_LITERAL("content")) - .Append(FILE_PATH_LITERAL("browser")) - .Append(FILE_PATH_LITERAL("gpu")) - .Append(FILE_PATH_LITERAL("gpu_driver_bug_list.json")); - if (!file_util::PathExists(data_file)) - return false; - int64 data_file_size64 = 0; - if (!file_util::GetFileSize(data_file, &data_file_size64)) - return false; - int data_file_size = static_cast<int>(data_file_size64); - scoped_ptr<char[]> data(new char[data_file_size]); - if (file_util::ReadFile(data_file, data.get(), data_file_size) != - data_file_size) - return false; - *json = std::string(data.get(), data_file_size); - return true; - } - - protected: - virtual void SetUp() { - gpu_info_.gpu.vendor_id = 0x10de; - gpu_info_.gpu.device_id = 0x0640; - gpu_info_.driver_vendor = "NVIDIA"; - gpu_info_.driver_version = "1.6.18"; - gpu_info_.driver_date = "7-14-2009"; - gpu_info_.machine_model = "MacBookPro 7.1"; - gpu_info_.gl_vendor = "NVIDIA Corporation"; - gpu_info_.gl_renderer = "NVIDIA GeForce GT 120 OpenGL Engine"; - gpu_info_.performance_stats.graphics = 5.0; - gpu_info_.performance_stats.gaming = 5.0; - gpu_info_.performance_stats.overall = 5.0; - } - - virtual void TearDown() { - } - - private: - GPUInfo gpu_info_; -}; - -TEST_F(GpuDriverBugListTest, CurrentDriverBugListValidation) { - scoped_ptr<GpuDriverBugList> list(GpuDriverBugList::Create()); - std::string json; - EXPECT_TRUE(GetCurrentDriverBugList(&json)); - EXPECT_TRUE(list->LoadList(json, GpuControlList::kAllOs)); - EXPECT_FALSE(list->contains_unknown_fields()); -} - -TEST_F(GpuDriverBugListTest, CurrentListForARM) { - scoped_ptr<GpuDriverBugList> list(GpuDriverBugList::Create()); - std::string json; - EXPECT_TRUE(GetCurrentDriverBugList(&json)); - EXPECT_TRUE(list->LoadList(json, GpuControlList::kAllOs)); - - GPUInfo gpu_info; - gpu_info.gl_vendor = "ARM"; - gpu_info.gl_renderer = "MALi_T604"; - std::set<int> bugs = list->MakeDecision( - GpuControlList::kOsAndroid, "4.1", gpu_info); - EXPECT_EQ(1u, bugs.count(gpu::USE_CLIENT_SIDE_ARRAYS_FOR_STREAM_BUFFERS)); -} - -TEST_F(GpuDriverBugListTest, CurrentListForImagination) { - scoped_ptr<GpuDriverBugList> list(GpuDriverBugList::Create()); - std::string json; - EXPECT_TRUE(GetCurrentDriverBugList(&json)); - EXPECT_TRUE(list->LoadList(json, GpuControlList::kAllOs)); - - GPUInfo gpu_info; - gpu_info.gl_vendor = "Imagination Technologies"; - gpu_info.gl_renderer = "PowerVR SGX 540"; - std::set<int> bugs = list->MakeDecision( - GpuControlList::kOsAndroid, "4.1", gpu_info); - EXPECT_EQ(1u, bugs.count(gpu::USE_CLIENT_SIDE_ARRAYS_FOR_STREAM_BUFFERS)); -} - -} // namespace content - diff --git a/content/browser/gpu/gpu_internals_ui.cc b/content/browser/gpu/gpu_internals_ui.cc index 6419ba81d1..b0978485fe 100644 --- a/content/browser/gpu/gpu_internals_ui.cc +++ b/content/browser/gpu/gpu_internals_ui.cc @@ -25,9 +25,9 @@ #include "content/public/browser/web_ui_message_handler.h" #include "content/public/common/content_client.h" #include "content/public/common/content_switches.h" -#include "content/public/common/gpu_feature_type.h" -#include "content/public/common/gpu_info.h" #include "content/public/common/url_constants.h" +#include "gpu/config/gpu_feature_type.h" +#include "gpu/config/gpu_info.h" #include "grit/content_resources.h" #include "third_party/angle/src/common/version.h" @@ -76,7 +76,7 @@ base::Value* NewStatusValue(const char* name, const char* status) { #if defined(OS_WIN) // Output DxDiagNode tree as nested array of {description,value} pairs -base::ListValue* DxDiagNodeToList(const DxDiagNode& node) { +base::ListValue* DxDiagNodeToList(const gpu::DxDiagNode& node) { base::ListValue* list = new ListValue(); for (std::map<std::string, std::string>::const_iterator it = node.values.begin(); @@ -85,7 +85,7 @@ base::ListValue* DxDiagNodeToList(const DxDiagNode& node) { list->Append(NewDescriptionValuePair(it->first, it->second)); } - for (std::map<std::string, DxDiagNode>::const_iterator it = + for (std::map<std::string, gpu::DxDiagNode>::const_iterator it = node.children.begin(); it != node.children.end(); ++it) { @@ -96,7 +96,7 @@ base::ListValue* DxDiagNodeToList(const DxDiagNode& node) { } #endif -std::string GPUDeviceToString(const GPUInfo::GPUDevice& gpu) { +std::string GPUDeviceToString(const gpu::GPUInfo::GPUDevice& gpu) { std::string vendor = base::StringPrintf("0x%04x", gpu.vendor_id); if (!gpu.vendor_string.empty()) vendor += " [" + gpu.vendor_string + "]"; @@ -108,7 +108,7 @@ std::string GPUDeviceToString(const GPUInfo::GPUDevice& gpu) { } base::DictionaryValue* GpuInfoAsDictionaryValue() { - GPUInfo gpu_info = GpuDataManagerImpl::GetInstance()->GetGPUInfo(); + gpu::GPUInfo gpu_info = GpuDataManagerImpl::GetInstance()->GetGPUInfo(); base::ListValue* basic_info = new base::ListValue(); basic_info->Append(NewDescriptionValuePair( "Initialization time", @@ -202,7 +202,8 @@ base::Value* GetFeatureStatus() { const GpuFeatureInfo kGpuFeatureInfo[] = { { "2d_canvas", - manager->IsFeatureBlacklisted(GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS), + manager->IsFeatureBlacklisted( + gpu::GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS), command_line.HasSwitch(switches::kDisableAccelerated2dCanvas) || !SupportsAccelerated2dCanvas(), "Accelerated 2D canvas is unavailable: either disabled at the command" @@ -212,7 +213,7 @@ base::Value* GetFeatureStatus() { { "compositing", manager->IsFeatureBlacklisted( - GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING), + gpu::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING), command_line.HasSwitch(switches::kDisableAcceleratedCompositing), "Accelerated compositing has been disabled, either via about:flags or" " command line. This adversely affects performance of all hardware" @@ -222,8 +223,8 @@ base::Value* GetFeatureStatus() { { "3d_css", manager->IsFeatureBlacklisted( - GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING) || - manager->IsFeatureBlacklisted(GPU_FEATURE_TYPE_3D_CSS), + gpu::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING) || + manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_3D_CSS), command_line.HasSwitch(switches::kDisableAcceleratedLayers), "Accelerated layers have been disabled at the command line.", false @@ -231,8 +232,8 @@ base::Value* GetFeatureStatus() { { "css_animation", manager->IsFeatureBlacklisted( - GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING) || - manager->IsFeatureBlacklisted(GPU_FEATURE_TYPE_3D_CSS), + gpu::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING) || + manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_3D_CSS), command_line.HasSwitch(cc::switches::kDisableThreadedAnimation) || command_line.HasSwitch(switches::kDisableAcceleratedCompositing) || command_line.HasSwitch(switches::kDisableAcceleratedLayers), @@ -241,7 +242,7 @@ base::Value* GetFeatureStatus() { }, { "webgl", - manager->IsFeatureBlacklisted(GPU_FEATURE_TYPE_WEBGL), + manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_WEBGL), #if defined(OS_ANDROID) !command_line.HasSwitch(switches::kEnableExperimentalWebGL), #else @@ -252,7 +253,7 @@ base::Value* GetFeatureStatus() { }, { "multisampling", - manager->IsFeatureBlacklisted(GPU_FEATURE_TYPE_MULTISAMPLING), + manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_MULTISAMPLING), command_line.HasSwitch(switches::kDisableGLMultisampling), "Multisampling has been disabled, either via about:flags or command" " line.", @@ -260,7 +261,7 @@ base::Value* GetFeatureStatus() { }, { "flash_3d", - manager->IsFeatureBlacklisted(GPU_FEATURE_TYPE_FLASH3D), + manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_FLASH3D), command_line.HasSwitch(switches::kDisableFlash3d), "Using 3d in flash has been disabled, either via about:flags or" " command line.", @@ -268,7 +269,7 @@ base::Value* GetFeatureStatus() { }, { "flash_stage3d", - manager->IsFeatureBlacklisted(GPU_FEATURE_TYPE_FLASH_STAGE3D), + manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_FLASH_STAGE3D), command_line.HasSwitch(switches::kDisableFlashStage3d), "Using Stage3d in Flash has been disabled, either via about:flags or" " command line.", @@ -277,8 +278,8 @@ base::Value* GetFeatureStatus() { { "flash_stage3d_baseline", manager->IsFeatureBlacklisted( - GPU_FEATURE_TYPE_FLASH_STAGE3D_BASELINE) || - manager->IsFeatureBlacklisted(GPU_FEATURE_TYPE_FLASH_STAGE3D), + gpu::GPU_FEATURE_TYPE_FLASH_STAGE3D_BASELINE) || + manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_FLASH_STAGE3D), command_line.HasSwitch(switches::kDisableFlashStage3d), "Using Stage3d Baseline profile in Flash has been disabled, either" " via about:flags or command line.", @@ -286,7 +287,7 @@ base::Value* GetFeatureStatus() { }, { "texture_sharing", - manager->IsFeatureBlacklisted(GPU_FEATURE_TYPE_TEXTURE_SHARING), + manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_TEXTURE_SHARING), command_line.HasSwitch(switches::kDisableImageTransportSurface), "Sharing textures between processes has been disabled, either via" " about:flags or command line.", @@ -295,7 +296,7 @@ base::Value* GetFeatureStatus() { { "video_decode", manager->IsFeatureBlacklisted( - GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE), + gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE), command_line.HasSwitch(switches::kDisableAcceleratedVideoDecode), "Accelerated video decode has been disabled, either via about:flags" " or command line.", @@ -303,7 +304,8 @@ base::Value* GetFeatureStatus() { }, { "video", - manager->IsFeatureBlacklisted(GPU_FEATURE_TYPE_ACCELERATED_VIDEO), + manager->IsFeatureBlacklisted( + gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO), command_line.HasSwitch(switches::kDisableAcceleratedVideo) || command_line.HasSwitch(switches::kDisableAcceleratedCompositing), "Accelerated video presentation has been disabled, either via" @@ -312,7 +314,7 @@ base::Value* GetFeatureStatus() { }, { "panel_fitting", - manager->IsFeatureBlacklisted(GPU_FEATURE_TYPE_PANEL_FITTING), + manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_PANEL_FITTING), #if defined(OS_CHROMEOS) command_line.HasSwitch(switches::kDisablePanelFitting), #else @@ -325,23 +327,15 @@ base::Value* GetFeatureStatus() { { "force_compositing_mode", manager->IsFeatureBlacklisted( - GPU_FEATURE_TYPE_FORCE_COMPOSITING_MODE) && + gpu::GPU_FEATURE_TYPE_FORCE_COMPOSITING_MODE) && !IsForceCompositingModeEnabled(), !IsForceCompositingModeEnabled() && !manager->IsFeatureBlacklisted( - GPU_FEATURE_TYPE_FORCE_COMPOSITING_MODE), + gpu::GPU_FEATURE_TYPE_FORCE_COMPOSITING_MODE), "Force compositing mode is off, either disabled at the command" " line or not supported by the current system.", false }, - { - "raster", - false, - !command_line.HasSwitch(switches::kEnableAcceleratedPainting), - "Accelerated rasterization has not been enabled or" - " is not supported by the current system.", - true - } }; const size_t kNumFeatures = sizeof(kGpuFeatureInfo) / sizeof(GpuFeatureInfo); @@ -384,7 +378,7 @@ base::Value* GetFeatureStatus() { if (kGpuFeatureInfo[i].name == "webgl" && (command_line.HasSwitch(switches::kDisableAcceleratedCompositing) || manager->IsFeatureBlacklisted( - GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING))) + gpu::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING))) status += "_readback"; bool has_thread = IsThreadedCompositingEnabled(); if (kGpuFeatureInfo[i].name == "compositing") { @@ -409,18 +403,18 @@ base::Value* GetFeatureStatus() { feature_status_list->Append( NewStatusValue(kGpuFeatureInfo[i].name.c_str(), status.c_str())); } - GpuSwitchingOption gpu_switching_option = + gpu::GpuSwitchingOption gpu_switching_option = GpuDataManagerImpl::GetInstance()->GetGpuSwitchingOption(); - if (gpu_switching_option != GPU_SWITCHING_OPTION_UNKNOWN) { + if (gpu_switching_option != gpu::GPU_SWITCHING_OPTION_UNKNOWN) { std::string gpu_switching; switch (gpu_switching_option) { - case GPU_SWITCHING_OPTION_AUTOMATIC: + case gpu::GPU_SWITCHING_OPTION_AUTOMATIC: gpu_switching = "gpu_switching_automatic"; break; - case GPU_SWITCHING_OPTION_FORCE_DISCRETE: + case gpu::GPU_SWITCHING_OPTION_FORCE_DISCRETE: gpu_switching = "gpu_switching_force_discrete"; break; - case GPU_SWITCHING_OPTION_FORCE_INTEGRATED: + case gpu::GPU_SWITCHING_OPTION_FORCE_INTEGRATED: gpu_switching = "gpu_switching_force_integrated"; break; default: diff --git a/content/browser/gpu/gpu_memory_test.cc b/content/browser/gpu/gpu_memory_test.cc index 832b947bce..fd85739b86 100644 --- a/content/browser/gpu/gpu_memory_test.cc +++ b/content/browser/gpu/gpu_memory_test.cc @@ -15,8 +15,8 @@ #include "content/shell/shell.h" #include "content/test/content_browser_test.h" #include "content/test/content_browser_test_utils.h" -#include "content/test/gpu/gpu_test_config.h" #include "gpu/command_buffer/service/gpu_switches.h" +#include "gpu/config/gpu_test_config.h" #include "net/base/net_util.h" namespace content { diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc index 560fed2a27..7de624c7e8 100644 --- a/content/browser/gpu/gpu_process_host.cc +++ b/content/browser/gpu/gpu_process_host.cc @@ -706,14 +706,14 @@ void GpuProcessHost::EstablishGpuChannel( // If GPU features are already blacklisted, no need to establish the channel. if (!GpuDataManagerImpl::GetInstance()->GpuAccessAllowed(NULL)) { - callback.Run(IPC::ChannelHandle(), GPUInfo()); + callback.Run(IPC::ChannelHandle(), gpu::GPUInfo()); return; } if (Send(new GpuMsg_EstablishChannel(client_id, share_context))) { channel_requests_.push(callback); } else { - callback.Run(IPC::ChannelHandle(), GPUInfo()); + callback.Run(IPC::ChannelHandle(), gpu::GPUInfo()); } if (!CommandLine::ForCurrentProcess()->HasSwitch( @@ -768,9 +768,14 @@ void GpuProcessHost::DeleteImage(int client_id, Send(new GpuMsg_DeleteImage(client_id, image_id, sync_point)); } -void GpuProcessHost::OnInitialized(bool result) { +void GpuProcessHost::OnInitialized(bool result, const gpu::GPUInfo& gpu_info) { UMA_HISTOGRAM_BOOLEAN("GPU.GPUProcessInitialized", result); initialized_ = result; + +#if defined(OS_WIN) + if (kind_ == GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED) + AcceleratedPresenter::SetAdapterLUID(gpu_info.adapter_luid); +#endif } void GpuProcessHost::OnChannelEstablished( @@ -793,7 +798,7 @@ void GpuProcessHost::OnChannelEstablished( if (!channel_handle.name.empty() && !GpuDataManagerImpl::GetInstance()->GpuAccessAllowed(NULL)) { Send(new GpuMsg_CloseChannel(channel_handle)); - callback.Run(IPC::ChannelHandle(), GPUInfo()); + callback.Run(IPC::ChannelHandle(), gpu::GPUInfo()); RouteOnUIThread(GpuHostMsg_OnLogMessage( logging::LOG_WARNING, "WARNING", @@ -925,13 +930,17 @@ void GpuProcessHost::OnAcceleratedSurfaceBuffersSwapped( // will forward to the RenderWidgetHostView via RenderProcessHostImpl and // RenderWidgetHostImpl. scoped_completion_runner.Release(); + + ViewHostMsg_CompositorSurfaceBuffersSwapped_Params view_params; + view_params.surface_id = params.surface_id; + view_params.surface_handle = params.surface_handle; + view_params.route_id = params.route_id; + view_params.size = params.size; + view_params.scale_factor = params.scale_factor; + view_params.gpu_process_host_id = host_id_; helper->DidReceiveBackingStoreMsg(ViewHostMsg_CompositorSurfaceBuffersSwapped( render_widget_id, - params.surface_id, - params.surface_handle, - params.route_id, - params.size, - host_id_)); + view_params)); } #endif // OS_MACOSX @@ -1126,6 +1135,7 @@ bool GpuProcessHost::LaunchGpuProcess(const std::string& channel_id) { switches::kDisableSeccompFilterSandbox, switches::kEnableGpuSandbox, switches::kEnableLogging, + switches::kEnableShareGroupAsyncTextureUpload, switches::kEnableVirtualGLContexts, switches::kGpuStartupDialog, switches::kLoggingLevel, @@ -1189,7 +1199,7 @@ void GpuProcessHost::SendOutstandingReplies() { while (!channel_requests_.empty()) { EstablishChannelCallback callback = channel_requests_.front(); channel_requests_.pop(); - callback.Run(IPC::ChannelHandle(), GPUInfo()); + callback.Run(IPC::ChannelHandle(), gpu::GPUInfo()); } while (!create_command_buffer_requests_.empty()) { @@ -1211,7 +1221,7 @@ void GpuProcessHost::BlockLiveOffscreenContexts() { std::string GpuProcessHost::GetShaderPrefixKey() { if (shader_prefix_key_.empty()) { - GPUInfo info = GpuDataManagerImpl::GetInstance()->GetGPUInfo(); + gpu::GPUInfo info = GpuDataManagerImpl::GetInstance()->GetGPUInfo(); std::string in_str = GetContentClient()->GetProduct() + "-" + info.gl_vendor + "-" + info.gl_renderer + "-" + diff --git a/content/browser/gpu/gpu_process_host.h b/content/browser/gpu/gpu_process_host.h index 6474d56da3..89103d7568 100644 --- a/content/browser/gpu/gpu_process_host.h +++ b/content/browser/gpu/gpu_process_host.h @@ -21,9 +21,9 @@ #include "content/common/gpu/gpu_process_launch_causes.h" #include "content/public/browser/browser_child_process_host_delegate.h" #include "content/public/browser/gpu_data_manager.h" -#include "content/public/common/gpu_info.h" #include "googleurl/src/gurl.h" #include "gpu/command_buffer/common/constants.h" +#include "gpu/config/gpu_info.h" #include "ipc/ipc_channel_proxy.h" #include "ipc/ipc_sender.h" #include "ui/gfx/native_widget_types.h" @@ -54,7 +54,7 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate, GPU_PROCESS_KIND_COUNT }; - typedef base::Callback<void(const IPC::ChannelHandle&, const GPUInfo&)> + typedef base::Callback<void(const IPC::ChannelHandle&, const gpu::GPUInfo&)> EstablishChannelCallback; typedef base::Callback<void(int32)> CreateCommandBufferCallback; @@ -148,7 +148,7 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate, virtual void OnProcessCrashed(int exit_code) OVERRIDE; // Message handlers. - void OnInitialized(bool result); + void OnInitialized(bool result, const gpu::GPUInfo& gpu_info); void OnChannelEstablished(const IPC::ChannelHandle& channel_handle); void OnCommandBufferCreated(const int32 route_id); void OnDestroyCommandBuffer(int32 surface_id); diff --git a/content/browser/gpu/gpu_process_host_ui_shim.cc b/content/browser/gpu/gpu_process_host_ui_shim.cc index a243115798..9598311056 100644 --- a/content/browser/gpu/gpu_process_host_ui_shim.cc +++ b/content/browser/gpu/gpu_process_host_ui_shim.cc @@ -248,7 +248,8 @@ void GpuProcessHostUIShim::OnLogMessage( level, header, message); } -void GpuProcessHostUIShim::OnGraphicsInfoCollected(const GPUInfo& gpu_info) { +void GpuProcessHostUIShim::OnGraphicsInfoCollected( + const gpu::GPUInfo& gpu_info) { // OnGraphicsInfoCollected is sent back after the GPU process successfully // initializes GL. TRACE_EVENT0("test_gpu", "OnGraphicsInfoCollected"); @@ -342,7 +343,7 @@ void GpuProcessHostUIShim::OnAcceleratedSurfaceBuffersSwapped( view->AcceleratedSurfaceBuffersSwapped(params, host_id_); } -void GpuProcessHostUIShim::OnFrameDrawn(const cc::LatencyInfo& latency_info) { +void GpuProcessHostUIShim::OnFrameDrawn(const ui::LatencyInfo& latency_info) { } void GpuProcessHostUIShim::OnAcceleratedSurfacePostSubBuffer( diff --git a/content/browser/gpu/gpu_process_host_ui_shim.h b/content/browser/gpu/gpu_process_host_ui_shim.h index 243cfd17cb..9f4329a10a 100644 --- a/content/browser/gpu/gpu_process_host_ui_shim.h +++ b/content/browser/gpu/gpu_process_host_ui_shim.h @@ -19,8 +19,8 @@ #include "base/threading/non_thread_safe.h" #include "content/common/content_export.h" #include "content/common/message_router.h" -#include "content/public/common/gpu_info.h" #include "content/public/common/gpu_memory_stats.h" +#include "gpu/config/gpu_info.h" #include "ipc/ipc_listener.h" #include "ipc/ipc_sender.h" @@ -28,7 +28,7 @@ struct GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params; struct GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params; struct GpuHostMsg_AcceleratedSurfaceRelease_Params; -namespace cc { +namespace ui { struct LatencyInfo; } @@ -93,7 +93,7 @@ class GpuProcessHostUIShim : public IPC::Listener, gfx::Size size); #endif - void OnGraphicsInfoCollected(const GPUInfo& gpu_info); + void OnGraphicsInfoCollected(const gpu::GPUInfo& gpu_info); void OnAcceleratedSurfaceBuffersSwapped( const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params); @@ -107,7 +107,7 @@ class GpuProcessHostUIShim : public IPC::Listener, void OnUpdateVSyncParameters(int surface_id, base::TimeTicks timebase, base::TimeDelta interval); - void OnFrameDrawn(const cc::LatencyInfo& latency_info); + void OnFrameDrawn(const ui::LatencyInfo& latency_info); // The serial number of the GpuProcessHost / GpuProcessHostUIShim pair. int host_id_; diff --git a/content/browser/gpu/gpu_switching_list.cc b/content/browser/gpu/gpu_switching_list.cc deleted file mode 100644 index 0097015925..0000000000 --- a/content/browser/gpu/gpu_switching_list.cc +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/browser/gpu/gpu_switching_list.h" - -#include "content/public/common/gpu_switching_option.h" - -namespace content { - -GpuSwitchingList::GpuSwitchingList() - : GpuControlList() { -} - -GpuSwitchingList::~GpuSwitchingList() { -} - -// static -GpuSwitchingList* GpuSwitchingList::Create() { - GpuSwitchingList* list = new GpuSwitchingList(); - list->AddSupportedFeature("force_integrated", - GPU_SWITCHING_OPTION_FORCE_INTEGRATED); - list->AddSupportedFeature("force_discrete", - GPU_SWITCHING_OPTION_FORCE_DISCRETE); - return list; -} - -} // namespace content - diff --git a/content/browser/gpu/gpu_switching_list.h b/content/browser/gpu/gpu_switching_list.h deleted file mode 100644 index 5c7d6c3b20..0000000000 --- a/content/browser/gpu/gpu_switching_list.h +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_BROWSER_GPU_GPU_SWITCHING_LIST_H_ -#define CONTENT_BROWSER_GPU_GPU_SWITCHING_LIST_H_ - -#include <string> - -#include "content/browser/gpu/gpu_control_list.h" - -namespace content { - -class CONTENT_EXPORT GpuSwitchingList : public GpuControlList { - public: - virtual ~GpuSwitchingList(); - - static GpuSwitchingList* Create(); - - private: - GpuSwitchingList(); - - DISALLOW_COPY_AND_ASSIGN(GpuSwitchingList); -}; - -} // namespace content - -#endif // CONTENT_BROWSER_GPU_GPU_SWITCHING_LIST_H_ - diff --git a/content/browser/gpu/gpu_switching_list.json b/content/browser/gpu/gpu_switching_list.json deleted file mode 100644 index 15d0aabf4b..0000000000 --- a/content/browser/gpu/gpu_switching_list.json +++ /dev/null @@ -1,107 +0,0 @@ -// Determines whether a certain gpu is prefered in a dual-gpu situation. -// A valid gpu_switching_list.json file are in the format of -// { -// "version": "x.y", -// "entries": [ -// { // entry 1 -// }, -// ... -// { // entry n -// } -// ] -// } -// -// Each entry contains the following fields (fields are optional unless -// specifically described as mandatory below): -// 1. "id" is an integer. 0 is reserved. This field is mandatory. -// 2. "os" contains "type" and an optional "version". "type" could be "macosx", -// "linux", "win", "chromeos", or "any". "any" is the same as not specifying -// "os". -// "version" is a VERSION structure (defined below). -// 3. "vendor_id" is a string. 0 is reserved. -// 4. "device_id" is an array of strings. 0 is reserved. -// 5. "multi_gpu_style" is a string, valid values include "optimus", and -// "amd_switchable". -// 6. "multi_gpu_category" is a string, valid values include "any", "primary", -// and "secondary". If unspecified, the default value is "primary". -// 7. "driver_vendor" is a STRING structure (defined below). -// 8. "driver_version" is a VERSION structure (defined below). -// 9. "driver_date" is a VERSION structure (defined below). -// The version is interpreted as "year.month.day". -// 10. "gl_vendor" is a STRING structure (defined below). -// 11. "gl_renderer" is a STRING structure (defined below). -// 12. "perf_graphics" is a FLOAT structure (defined below). -// 13. "perf_gaming" is a FLOAT structure (defined below). -// 14. "perf_overall" is a FLOAT structure (defined below). -// 15. "machine_model" contais "name" and an optional "version". "name" is a -// STRING structure and "version" is a VERSION structure (defined below). -// 16. "gpu_count" is a INT structure (defined below). -// 17 "cpu_info" is a STRING structure (defined below). -// 18. "exceptions" is a list of entries. -// 19. "features" is a list of gpu switching options, including -// "force_discrete" and "force_integrated". -// This field is mandatory. -// 20. "description" has the description of the entry. -// 21. "webkit_bugs" is an array of associated webkit bug numbers. -// 22. "cr_bugs" is an array of associated webkit bug numbers. -// 23. "browser_version" is a VERSION structure (defined below). If this -// condition is not satisfied, the entry will be ignored. If it is not -// present, then the entry applies to all versions of the browser. -// 24. "disabled" is a boolean. If it is present, the entry will be skipped. -// This can not be used in exceptions. -// -// VERSION includes "op", "style", "number", and "number2". "op" can be any of -// the following values: "=", "<", "<=", ">", ">=", "any", "between". "style" -// is optional and can be "lexical" or "numerical"; if it's not specified, it -// defaults to "numerical". "number2" is only used if "op" is "between". -// "between" is "number <= * <= number2". -// "number" is used for all "op" values except "any". "number" and "number2" -// are in the format of x, x.x, x.x.x, etc. -// Only "driver_version" supports lexical style if the format is major.minor; -// in that case, major is still numerical, but minor is lexical. -// -// STRING includes "op" and "value". "op" can be any of the following values: -// "contains", "beginwith", "endwith", "=". "value" is a string. -// -// FLOAT includes "op" "value", and "value2". "op" can be any of the -// following values: "=", "<", "<=", ">", ">=", "any", "between". "value2" is -// only used if "op" is "between". "value" is used for all "op" values except -// "any". "value" and "value2" are valid float numbers. -// INT is very much like FLOAT, except that the values need to be integers. - -{ - "name": "gpu switching list", - // Please update the version number whenever you change this file. - "version": "1.0", - "entries": [ - { - "id": 1, - "description": "Force to use discrete GPU on older MacBookPro models.", - "cr_bugs": [113703], - "os": { - "type": "macosx", - "version": { - "op": ">=", - "number": "10.7" - } - }, - "machine_model": { - "name": { - "op": "=", - "value": "MacBookPro" - }, - "version": { - "op": "<", - "number": "8" - } - }, - "gpu_count": { - "op": "=", - "value": "2" - }, - "features": [ - "force_discrete" - ] - } - ] -} diff --git a/content/browser/gpu/gpu_switching_list_unittest.cc b/content/browser/gpu/gpu_switching_list_unittest.cc deleted file mode 100644 index 82d07c67b5..0000000000 --- a/content/browser/gpu/gpu_switching_list_unittest.cc +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <vector> - -#include "base/base_paths.h" -#include "base/file_util.h" -#include "base/files/file_path.h" -#include "base/memory/scoped_ptr.h" -#include "base/path_service.h" -#include "content/browser/gpu/gpu_switching_list.h" -#include "content/public/common/gpu_info.h" -#include "content/public/common/gpu_switching_option.h" -#include "testing/gtest/include/gtest/gtest.h" - -#define LONG_STRING_CONST(...) #__VA_ARGS__ - -const char kOsVersion[] = "10.6.4"; - -namespace content { - -class GpuSwitchingListTest : public testing::Test { - public: - GpuSwitchingListTest() { } - - virtual ~GpuSwitchingListTest() { } - - const GPUInfo& gpu_info() const { - return gpu_info_; - } - - protected: - virtual void SetUp() { - gpu_info_.gpu.vendor_id = 0x10de; - gpu_info_.gpu.device_id = 0x0640; - gpu_info_.driver_vendor = "NVIDIA"; - gpu_info_.driver_version = "1.6.18"; - gpu_info_.driver_date = "7-14-2009"; - gpu_info_.machine_model = "MacBookPro 7.1"; - gpu_info_.gl_vendor = "NVIDIA Corporation"; - gpu_info_.gl_renderer = "NVIDIA GeForce GT 120 OpenGL Engine"; - gpu_info_.performance_stats.graphics = 5.0; - gpu_info_.performance_stats.gaming = 5.0; - gpu_info_.performance_stats.overall = 5.0; - } - - virtual void TearDown() { - } - - private: - GPUInfo gpu_info_; -}; - -TEST_F(GpuSwitchingListTest, CurrentSwitchingListValidation) { - base::FilePath data_file; - ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &data_file)); - data_file = - data_file.Append(FILE_PATH_LITERAL("content")) - .Append(FILE_PATH_LITERAL("browser")) - .Append(FILE_PATH_LITERAL("gpu")) - .Append(FILE_PATH_LITERAL("gpu_switching_list.json")); - ASSERT_TRUE(file_util::PathExists(data_file)); - int64 data_file_size64 = 0; - ASSERT_TRUE(file_util::GetFileSize(data_file, &data_file_size64)); - int data_file_size = static_cast<int>(data_file_size64); - scoped_ptr<char[]> data(new char[data_file_size]); - ASSERT_EQ(data_file_size, - file_util::ReadFile(data_file, data.get(), data_file_size)); - std::string json_string(data.get(), data_file_size); - scoped_ptr<GpuSwitchingList> switching_list(GpuSwitchingList::Create()); - EXPECT_TRUE(switching_list->LoadList(json_string, GpuControlList::kAllOs)); - EXPECT_FALSE(switching_list->contains_unknown_fields()); -} - -TEST_F(GpuSwitchingListTest, GpuSwitching) { - const std::string json = LONG_STRING_CONST( - { - "name": "gpu switching list", - "version": "0.1", - "entries": [ - { - "id": 1, - "os": { - "type": "macosx" - }, - "features": [ - "force_discrete" - ] - }, - { - "id": 2, - "os": { - "type": "win" - }, - "features": [ - "force_integrated" - ] - } - ] - } - ); - scoped_ptr<GpuSwitchingList> switching_list(GpuSwitchingList::Create()); - EXPECT_TRUE(switching_list->LoadList(json, GpuControlList::kAllOs)); - std::set<int> switching = switching_list->MakeDecision( - GpuControlList::kOsMacosx, kOsVersion, gpu_info()); - EXPECT_EQ(1u, switching.size()); - EXPECT_EQ(1u, switching.count(GPU_SWITCHING_OPTION_FORCE_DISCRETE)); - std::vector<uint32> entries; - switching_list->GetDecisionEntries(&entries, false); - ASSERT_EQ(1u, entries.size()); - EXPECT_EQ(1u, entries[0]); - - switching_list.reset(GpuSwitchingList::Create()); - EXPECT_TRUE(switching_list->LoadList(json, GpuControlList::kAllOs)); - switching = switching_list->MakeDecision( - GpuControlList::kOsWin, kOsVersion, gpu_info()); - EXPECT_EQ(1u, switching.size()); - EXPECT_EQ(1u, switching.count(GPU_SWITCHING_OPTION_FORCE_INTEGRATED)); - switching_list->GetDecisionEntries(&entries, false); - ASSERT_EQ(1u, entries.size()); - EXPECT_EQ(2u, entries[0]); -} - -} // namespace content - diff --git a/content/browser/gpu/gpu_util.cc b/content/browser/gpu/gpu_util.cc deleted file mode 100644 index 5aa5433c82..0000000000 --- a/content/browser/gpu/gpu_util.cc +++ /dev/null @@ -1,191 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/browser/gpu/gpu_util.h" - -#include <vector> - -#include "base/command_line.h" -#include "base/metrics/histogram.h" -#include "base/string_util.h" -#include "base/sys_info.h" -#include "base/version.h" -#include "content/browser/gpu/gpu_blacklist.h" -#include "content/public/common/content_switches.h" -#include "content/public/common/gpu_feature_type.h" -#include "ui/gl/gl_switches.h" - -namespace content { -namespace { - -enum GpuFeatureStatus { - kGpuFeatureEnabled = 0, - kGpuFeatureBlacklisted = 1, - kGpuFeatureDisabled = 2, // disabled by user but not blacklisted - kGpuFeatureNumStatus -}; - -#if defined(OS_WIN) - -enum WinSubVersion { - kWinOthers = 0, - kWinXP, - kWinVista, - kWin7, - kNumWinSubVersions -}; - -int GetGpuBlacklistHistogramValueWin(GpuFeatureStatus status) { - static WinSubVersion sub_version = kNumWinSubVersions; - if (sub_version == kNumWinSubVersions) { - sub_version = kWinOthers; - std::string version_str = base::SysInfo::OperatingSystemVersion(); - size_t pos = version_str.find_first_not_of("0123456789."); - if (pos != std::string::npos) - version_str = version_str.substr(0, pos); - Version os_version(version_str); - if (os_version.IsValid() && os_version.components().size() >= 2) { - const std::vector<uint16>& version_numbers = os_version.components(); - if (version_numbers[0] == 5) - sub_version = kWinXP; - else if (version_numbers[0] == 6 && version_numbers[1] == 0) - sub_version = kWinVista; - else if (version_numbers[0] == 6 && version_numbers[1] == 1) - sub_version = kWin7; - } - } - int entry_index = static_cast<int>(sub_version) * kGpuFeatureNumStatus; - switch (status) { - case kGpuFeatureEnabled: - break; - case kGpuFeatureBlacklisted: - entry_index++; - break; - case kGpuFeatureDisabled: - entry_index += 2; - break; - } - return entry_index; -} -#endif // OS_WIN - -} // namespace anonymous - -GpuSwitchingOption StringToGpuSwitchingOption( - const std::string& switching_string) { - if (switching_string == switches::kGpuSwitchingOptionNameAutomatic) - return GPU_SWITCHING_OPTION_AUTOMATIC; - if (switching_string == switches::kGpuSwitchingOptionNameForceIntegrated) - return GPU_SWITCHING_OPTION_FORCE_INTEGRATED; - if (switching_string == switches::kGpuSwitchingOptionNameForceDiscrete) - return GPU_SWITCHING_OPTION_FORCE_DISCRETE; - return GPU_SWITCHING_OPTION_UNKNOWN; -} - -std::string GpuSwitchingOptionToString(GpuSwitchingOption option) { - switch (option) { - case GPU_SWITCHING_OPTION_AUTOMATIC: - return switches::kGpuSwitchingOptionNameAutomatic; - case GPU_SWITCHING_OPTION_FORCE_INTEGRATED: - return switches::kGpuSwitchingOptionNameForceIntegrated; - case GPU_SWITCHING_OPTION_FORCE_DISCRETE: - return switches::kGpuSwitchingOptionNameForceDiscrete; - default: - return "unknown"; - } -} - -void UpdateStats(const GpuBlacklist* blacklist, - const std::set<int>& blacklisted_features) { - uint32 max_entry_id = blacklist->max_entry_id(); - if (max_entry_id == 0) { - // GPU Blacklist was not loaded. No need to go further. - return; - } - - const CommandLine& command_line = *CommandLine::ForCurrentProcess(); - bool disabled = false; - if (blacklisted_features.size() == 0) { - UMA_HISTOGRAM_ENUMERATION("GPU.BlacklistTestResultsPerEntry", - 0, max_entry_id + 1); - } else { - std::vector<uint32> flag_entries; - blacklist->GetDecisionEntries(&flag_entries, disabled); - DCHECK_GT(flag_entries.size(), 0u); - for (size_t i = 0; i < flag_entries.size(); ++i) { - UMA_HISTOGRAM_ENUMERATION("GPU.BlacklistTestResultsPerEntry", - flag_entries[i], max_entry_id + 1); - } - } - - // This counts how many users are affected by a disabled entry - this allows - // us to understand the impact of an entry before enable it. - std::vector<uint32> flag_disabled_entries; - disabled = true; - blacklist->GetDecisionEntries(&flag_disabled_entries, disabled); - for (size_t i = 0; i < flag_disabled_entries.size(); ++i) { - UMA_HISTOGRAM_ENUMERATION("GPU.BlacklistTestResultsPerDisabledEntry", - flag_disabled_entries[i], max_entry_id + 1); - } - - const GpuFeatureType kGpuFeatures[] = { - GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS, - GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING, - GPU_FEATURE_TYPE_WEBGL - }; - const std::string kGpuBlacklistFeatureHistogramNames[] = { - "GPU.BlacklistFeatureTestResults.Accelerated2dCanvas", - "GPU.BlacklistFeatureTestResults.AcceleratedCompositing", - "GPU.BlacklistFeatureTestResults.Webgl" - }; - const bool kGpuFeatureUserFlags[] = { - command_line.HasSwitch(switches::kDisableAccelerated2dCanvas), - command_line.HasSwitch(switches::kDisableAcceleratedCompositing), -#if defined(OS_ANDROID) - !command_line.HasSwitch(switches::kEnableExperimentalWebGL) -#else - command_line.HasSwitch(switches::kDisableExperimentalWebGL) -#endif - }; -#if defined(OS_WIN) - const std::string kGpuBlacklistFeatureHistogramNamesWin[] = { - "GPU.BlacklistFeatureTestResultsWindows.Accelerated2dCanvas", - "GPU.BlacklistFeatureTestResultsWindows.AcceleratedCompositing", - "GPU.BlacklistFeatureTestResultsWindows.Webgl" - }; -#endif - const size_t kNumFeatures = - sizeof(kGpuFeatures) / sizeof(GpuFeatureType); - for (size_t i = 0; i < kNumFeatures; ++i) { - // We can't use UMA_HISTOGRAM_ENUMERATION here because the same name is - // expected if the macro is used within a loop. - GpuFeatureStatus value = kGpuFeatureEnabled; - if (blacklisted_features.count(kGpuFeatures[i])) - value = kGpuFeatureBlacklisted; - else if (kGpuFeatureUserFlags[i]) - value = kGpuFeatureDisabled; - base::HistogramBase* histogram_pointer = base::LinearHistogram::FactoryGet( - kGpuBlacklistFeatureHistogramNames[i], - 1, kGpuFeatureNumStatus, kGpuFeatureNumStatus + 1, - base::HistogramBase::kUmaTargetedHistogramFlag); - histogram_pointer->Add(value); -#if defined(OS_WIN) - histogram_pointer = base::LinearHistogram::FactoryGet( - kGpuBlacklistFeatureHistogramNamesWin[i], - 1, kNumWinSubVersions * kGpuFeatureNumStatus, - kNumWinSubVersions * kGpuFeatureNumStatus + 1, - base::HistogramBase::kUmaTargetedHistogramFlag); - histogram_pointer->Add(GetGpuBlacklistHistogramValueWin(value)); -#endif - } -} - -void MergeFeatureSets(std::set<int>* dst, const std::set<int>& src) { - DCHECK(dst); - if (src.empty()) - return; - dst->insert(src.begin(), src.end()); -} - -} // namespace content diff --git a/content/browser/gpu/gpu_util.h b/content/browser/gpu/gpu_util.h deleted file mode 100644 index 0a277fc46f..0000000000 --- a/content/browser/gpu/gpu_util.h +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_BROWSER_GPU_GPU_UTIL_H_ -#define CONTENT_BROWSER_GPU_GPU_UTIL_H_ - -#include <set> -#include <string> - -#include "base/basictypes.h" -#include "build/build_config.h" -#include "content/common/content_export.h" -#include "content/public/common/gpu_switching_option.h" - -namespace content { -class GpuBlacklist; - -// Maps string to GpuSwitchingOption; returns GPU_SWITCHING_UNKNOWN if an -// unknown name is input (case-sensitive). -CONTENT_EXPORT GpuSwitchingOption StringToGpuSwitchingOption( - const std::string& switching_string); - -// Gets a string version of a GpuSwitchingOption. -CONTENT_EXPORT std::string GpuSwitchingOptionToString( - GpuSwitchingOption option); - -// Send UMA histograms about the enabled features. -CONTENT_EXPORT void UpdateStats( - const GpuBlacklist* blacklist, const std::set<int>& blacklisted_features); - -// Merge features in src into dst. -CONTENT_EXPORT void MergeFeatureSets( - std::set<int>* dst, const std::set<int>& src); - -} // namespace content - -#endif // CONTENT_BROWSER_GPU_GPU_UTIL_H_ - diff --git a/content/browser/gpu/gpu_util_unittest.cc b/content/browser/gpu/gpu_util_unittest.cc deleted file mode 100644 index 5bc7d77bb6..0000000000 --- a/content/browser/gpu/gpu_util_unittest.cc +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/browser/gpu/gpu_util.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "ui/gl/gl_switches.h" - -namespace content { - -TEST(GpuUtilTest, GpuSwitchingOptionFromString) { - // Test StringToGpuSwitchingOption. - EXPECT_EQ(StringToGpuSwitchingOption( - switches::kGpuSwitchingOptionNameAutomatic), - GPU_SWITCHING_OPTION_AUTOMATIC); - EXPECT_EQ(StringToGpuSwitchingOption( - switches::kGpuSwitchingOptionNameForceDiscrete), - GPU_SWITCHING_OPTION_FORCE_DISCRETE); - EXPECT_EQ(StringToGpuSwitchingOption( - switches::kGpuSwitchingOptionNameForceIntegrated), - GPU_SWITCHING_OPTION_FORCE_INTEGRATED); - EXPECT_EQ(StringToGpuSwitchingOption("xxx"), GPU_SWITCHING_OPTION_UNKNOWN); -} - -TEST(GpuUtilTest, GpuSwitchingOptionToString) { - // Test GpuSwitchingOptionToString. - EXPECT_STREQ( - GpuSwitchingOptionToString(GPU_SWITCHING_OPTION_AUTOMATIC).c_str(), - switches::kGpuSwitchingOptionNameAutomatic); - EXPECT_STREQ( - GpuSwitchingOptionToString(GPU_SWITCHING_OPTION_FORCE_DISCRETE).c_str(), - switches::kGpuSwitchingOptionNameForceDiscrete); - EXPECT_STREQ( - GpuSwitchingOptionToString(GPU_SWITCHING_OPTION_FORCE_INTEGRATED).c_str(), - switches::kGpuSwitchingOptionNameForceIntegrated); -} - -TEST(GpuUtilTest, MergeFeatureSets) { - { - // Merge two empty sets. - std::set<int> src; - std::set<int> dst; - EXPECT_TRUE(dst.empty()); - MergeFeatureSets(&dst, src); - EXPECT_TRUE(dst.empty()); - } - { - // Merge an empty set into a set with elements. - std::set<int> src; - std::set<int> dst; - dst.insert(1); - EXPECT_EQ(1u, dst.size()); - MergeFeatureSets(&dst, src); - EXPECT_EQ(1u, dst.size()); - } - { - // Merge two sets where the source elements are already in the target set. - std::set<int> src; - std::set<int> dst; - src.insert(1); - dst.insert(1); - EXPECT_EQ(1u, dst.size()); - MergeFeatureSets(&dst, src); - EXPECT_EQ(1u, dst.size()); - } - { - // Merge two sets with different elements. - std::set<int> src; - std::set<int> dst; - src.insert(1); - dst.insert(2); - EXPECT_EQ(1u, dst.size()); - MergeFeatureSets(&dst, src); - EXPECT_EQ(2u, dst.size()); - } -} - -} // namespace content diff --git a/content/browser/gpu/software_rendering_list.json b/content/browser/gpu/software_rendering_list.json deleted file mode 100644 index 56eaf86670..0000000000 --- a/content/browser/gpu/software_rendering_list.json +++ /dev/null @@ -1,1099 +0,0 @@ -// Determines whether certain gpu-related features are blacklisted or not. -// A valid software_rendering_list.json file are in the format of -// { -// "version": "x.y", -// "entries": [ -// { // entry 1 -// }, -// ... -// { // entry n -// } -// ] -// } -// -// Each entry contains the following fields (fields are optional unless -// specifically described as mandatory below): -// 1. "id" is an integer. 0 is reserved. This field is mandatory. -// 2. "os" contains "type" and an optional "version". "type" could be "macosx", -// "linux", "win", "chromeos", or "any". "any" is the same as not specifying -// "os". -// "version" is a VERSION structure (defined below). -// 3. "vendor_id" is a string. 0 is reserved. -// 4. "device_id" is an array of strings. 0 is reserved. -// 5. "multi_gpu_style" is a string, valid values include "optimus", and -// "amd_switchable". -// 6. "multi_gpu_category" is a string, valid values include "any", "primary", -// and "secondary". If unspecified, the default value is "primary". -// 7. "driver_vendor" is a STRING structure (defined below). -// 8. "driver_version" is a VERSION structure (defined below). -// 9. "driver_date" is a VERSION structure (defined below). -// The version is interpreted as "year.month.day". -// 10. "gl_vendor" is a STRING structure (defined below). -// 11. "gl_renderer" is a STRING structure (defined below). -// 12. "gl_extensions" is a STRING structure (defined below). -// 13. "perf_graphics" is a FLOAT structure (defined below). -// 14. "perf_gaming" is a FLOAT structure (defined below). -// 15. "perf_overall" is a FLOAT structure (defined below). -// 16. "machine_model" contais "name" and an optional "version". "name" is a -// STRING structure and "version" is a VERSION structure (defined below). -// 17. "gpu_count" is a INT structure (defined below). -// 18 "cpu_info" is a STRING structure (defined below). -// 19. "exceptions" is a list of entries. -// 20. "features" is a list of gpu feature strings, valid values include -// "accelerated_2d_canvas", "accelerated_compositing", "webgl", -// "multisampling", "flash_3d", "flash_stage3d", "texture_sharing", -// "accelerated_video", "accelerated_video_decode", "panel_fitting", -// "force_compositing_mode", and "all". -// This field is mandatory. -// 21. "description" has the description of the entry. -// 22. "webkit_bugs" is an array of associated webkit bug numbers. -// 23. "cr_bugs" is an array of associated webkit bug numbers. -// 24. "browser_version" is a VERSION structure (defined below). If this -// condition is not satisfied, the entry will be ignored. If it is not -// present, then the entry applies to all versions of the browser. -// 25. "disabled" is a boolean. If it is present, the entry will be skipped. -// This can not be used in exceptions. -// -// VERSION includes "op", "style", "number", and "number2". "op" can be any of -// the following values: "=", "<", "<=", ">", ">=", "any", "between". "style" -// is optional and can be "lexical" or "numerical"; if it's not specified, it -// defaults to "numerical". "number2" is only used if "op" is "between". -// "between" is "number <= * <= number2". -// "number" is used for all "op" values except "any". "number" and "number2" -// are in the format of x, x.x, x.x.x, etc. -// Only "driver_version" supports lexical style if the format is major.minor; -// in that case, major is still numerical, but minor is lexical. -// -// STRING includes "op" and "value". "op" can be any of the following values: -// "contains", "beginwith", "endwith", "=". "value" is a string. -// -// FLOAT includes "op" "value", and "value2". "op" can be any of the -// following values: "=", "<", "<=", ">", ">=", "any", "between". "value2" is -// only used if "op" is "between". "value" is used for all "op" values except -// "any". "value" and "value2" are valid float numbers. -// INT is very much like FLOAT, except that the values need to be integers. - -{ - "name": "software rendering list", - // Please update the version number whenever you change this file. - "version": "5.3", - "entries": [ - { - "id": 1, - "description": "ATI Radeon X1900 is not compatible with WebGL on the Mac.", - "webkit_bugs": [47028], - "os": { - "type": "macosx" - }, - "vendor_id": "0x1002", - "device_id": ["0x7249"], - "features": [ - "webgl", - "flash_3d", - "flash_stage3d" - ] - }, - { - "id": 3, - "description": "GL driver is software rendered. Accelerated compositing is disabled.", - "cr_bugs": [59302], - "os": { - "type": "linux" - }, - "gl_renderer": { - "op": "contains", - "value": "software" - }, - "features": [ - "accelerated_compositing" - ] - }, - { - "id": 4, - "description": "The Intel Mobile 945 Express family of chipsets is not compatible with WebGL.", - "os": { - "type": "any" - }, - "vendor_id": "0x8086", - "device_id": ["0x27AE"], - "features": [ - "webgl", - "flash_3d", - "flash_stage3d" - ] - }, - { - "id": 5, - "description": "ATI/AMD cards with older or third-party drivers in Linux are crash-prone.", - "cr_bugs": [71381, 76428, 73910, 101225, 136240], - "os": { - "type": "linux" - }, - "vendor_id": "0x1002", - "exceptions": [ - { - "driver_vendor": { - "op": "contains", - "value": "AMD" - }, - "driver_version": { - "op": ">=", - "style": "lexical", - "number": "8.98" - } - } - ], - "features": [ - "all" - ] - }, - { - "id": 8, - "description": "NVIDIA GeForce FX Go5200 is assumed to be buggy.", - "cr_bugs": [72938], - "os": { - "type": "any" - }, - "vendor_id": "0x10de", - "device_id": ["0x0324"], - "features": [ - "all" - ] - }, - { - "id": 10, - "description": "NVIDIA GeForce 7300 GT on Mac does not support WebGL.", - "cr_bugs": [73794], - "os": { - "type": "macosx" - }, - "vendor_id": "0x10de", - "device_id": ["0x0393"], - "features": [ - "webgl", - "flash_3d", - "flash_stage3d" - ] - }, - { - "id": 12, - "description": "Drivers older than 2009-01 on Windows are possibly unreliable.", - "cr_bugs": [72979, 89802], - "os": { - "type": "win" - }, - "driver_date": { - "op": "<", - "number": "2009.1" - }, - "exceptions": [ - { - "vendor_id": "0x8086", - "device_id": ["0x29a2"], - "driver_version": { - "op": ">=", - "number": "7.15.10.1624" - } - } - ], - "features": [ - "accelerated_2d_canvas", - "accelerated_video", - "accelerated_video_decode", - "3d_css", - "multisampling", - "flash_3d", - "force_compositing_mode" - ] - }, - { - "id": 13, - "description": "ATI drivers older than 10.6 on Windows XP are possibly unreliable.", - "cr_bugs": [74212], - "os": { - "type": "win", - "version": { - "op": "=", - "number": "5" - } - }, - "vendor_id": "0x1002", - "driver_version": { - "op": "<", - "number": "8.741" - }, - "features": [ - "accelerated_video", - "accelerated_video_decode", - "3d_css", - "multisampling", - "flash_3d", - "force_compositing_mode" - ] - }, - { - "id": 14, - "description": "NVIDIA drivers older than 257.21 on Windows XP are possibly unreliable.", - "cr_bugs": [74212], - "os": { - "type": "win", - "version": { - "op": "=", - "number": "5" - } - }, - "vendor_id": "0x10de", - "driver_version": { - "op": "<", - "number": "6.14.12.5721" - }, - "features": [ - "accelerated_video", - "accelerated_video_decode", - "3d_css", - "multisampling", - "flash_3d", - "force_compositing_mode" - ] - }, - { - "id": 15, - "description": "Intel drivers older than 14.42.7.5294 on Windows XP are possibly unreliable.", - "cr_bugs": [74212], - "os": { - "type": "win", - "version": { - "op": "=", - "number": "5" - } - }, - "vendor_id": "0x8086", - "driver_version": { - "op": "<", - "number": "6.14.10.5294" - }, - "features": [ - "accelerated_video", - "accelerated_video_decode", - "3d_css", - "multisampling", - "flash_3d", - "force_compositing_mode" - ] - }, - { - "id": 16, - "description": "Multisampling is buggy in ATI cards on older MacOSX.", - "cr_bugs": [67752, 83153], - "os": { - "type": "macosx", - "version": { - "op": "<", - "number": "10.7.2" - } - }, - "vendor_id": "0x1002", - "features": [ - "multisampling" - ] - }, - { - "id": 17, - "description": "Intel mesa drivers are crash-prone.", - "cr_bugs": [76703, 164555], - "os": { - "type": "linux" - }, - "vendor_id": "0x8086", - "exceptions": [ - { - "device_id": ["0x0102", "0x0106", "0x0112", "0x0116", "0x0122", "0x0126", "0x010a", "0x0152", "0x0156", "0x015a", "0x0162", "0x0166"], - "driver_version": { - "op": ">=", - "number": "8.0" - } - }, - { - "device_id": ["0xa001", "0xa002", "0xa011", "0xa012", "0x29a2", "0x2992", "0x2982", "0x2972", "0x2a12", "0x2a42", "0x2e02", "0x2e12", "0x2e22", "0x2e32", "0x2e42", "0x2e92"], - "driver_version": { - "op": ">", - "number": "8.0.2" - } - }, - { - "device_id": ["0x0042", "0x0046"], - "driver_version": { - "op": ">=", - "number": "8.0.2" - } - }, - { - "device_id": ["0x2a02"], - "driver_version": { - "op": ">=", - "number": "9.1" - } - } - ], - "features": [ - "all" - ] - }, - { - "id": 18, - "description": "NVIDIA Quadro FX 1500 is buggy.", - "cr_bugs": [84701], - "os": { - "type": "linux" - }, - "vendor_id": "0x10de", - "device_id": ["0x029e"], - "features": [ - "all" - ] - }, - { - "id": 19, - "description": "GPU acceleration is no longer supported in Leopard.", - "cr_bugs": [87157, 130495], - "os": { - "type": "macosx", - "version": { - "op": "=", - "number": "10.5" - } - }, - "features": [ - "all" - ] - }, - { - "id": 23, - "description": "Mesa drivers in linux older than 7.11 are assumed to be buggy.", - "os": { - "type": "linux" - }, - "driver_vendor": { - "op": "=", - "value": "Mesa" - }, - "driver_version": { - "op": "<", - "number": "7.11" - }, - "features": [ - "all" - ] - }, - { - "id": 24, - "description": "Accelerated 2d canvas is unstable in Linux at the moment.", - "os": { - "type": "linux" - }, - "features": [ - "accelerated_2d_canvas" - ] - }, - { - "id": 27, - "description": "ATI/AMD cards with older drivers in Linux are crash-prone.", - "cr_bugs": [95934, 94973, 136240], - "os": { - "type": "linux" - }, - "gl_vendor": { - "op": "beginwith", - "value": "ATI" - }, - "exceptions": [ - { - "driver_vendor": { - "op": "contains", - "value": "AMD" - }, - "driver_version": { - "op": ">=", - "style": "lexical", - "number": "8.98" - } - } - ], - "features": [ - "all" - ] - }, - { - "id": 28, - "description": "ATI/AMD cards with third-party drivers in Linux are crash-prone.", - "cr_bugs": [95934, 94973], - "os": { - "type": "linux" - }, - "gl_vendor": { - "op": "beginwith", - "value": "X.Org" - }, - "gl_renderer": { - "op": "contains", - "value": "AMD" - }, - "features": [ - "all" - ] - }, - { - "id": 29, - "description": "ATI/AMD cards with third-party drivers in Linux are crash-prone.", - "cr_bugs": [95934, 94973], - "os": { - "type": "linux" - }, - "gl_vendor": { - "op": "beginwith", - "value": "X.Org" - }, - "gl_renderer": { - "op": "contains", - "value": "ATI" - }, - "features": [ - "all" - ] - }, - { - "id": 30, - "description": "NVIDIA cards with nouveau drivers in Linux are crash-prone.", - "cr_bugs": [94103], - "os": { - "type": "linux" - }, - "vendor_id": "0x10de", - "gl_vendor": { - "op": "beginwith", - "value": "nouveau" - }, - "features": [ - "all" - ] - }, - { - "id": 32, - "description": "Accelerated 2d canvas is disabled on Windows systems with low perf stats.", - "cr_bugs": [116350, 151500], - "os": { - "type": "win" - }, - "perf_overall": { - "op": "<", - "value": "3.5" - }, - "exceptions": [ - { - "perf_gaming": { - "op": ">", - "value": "3.5" - } - }, - { - "cpu_info": { - "op": "contains", - "value": "Atom" - } - } - ], - "features": [ - "accelerated_2d_canvas" - ] - }, - { - "id": 33, - "description": "Multisampling is buggy in Intel IvyBridge.", - "cr_bugs": [116370], - "os": { - "type": "linux" - }, - "vendor_id": "0x8086", - "device_id": ["0x0152", "0x0156", "0x015a", "0x0162", "0x0166"], - "features": [ - "multisampling" - ] - }, - { - "id": 34, - "description": "S3 Trio (used in Virtual PC) is not compatible.", - "cr_bugs": [119948], - "os": { - "type": "win" - }, - "vendor_id": "0x5333", - "device_id": ["0x8811"], - "features": [ - "all" - ] - }, - { - "id": 35, - "description": "Stage3D is not supported on Linux.", - "cr_bugs": [129848], - "os": { - "type": "linux" - }, - "features": [ - "flash_stage3d" - ] - }, - { - "id": 37, - "description": "Drivers are unreliable for Optimus on Linux.", - "cr_bugs": [131308], - "os": { - "type": "linux" - }, - "multi_gpu_style": "optimus", - "features": [ - "all" - ] - }, - { - "id": 38, - "description": "Accelerated 2D canvas is unstable for NVidia GeForce 9400M on Lion.", - "cr_bugs": [130495], - "os": { - "type": "macosx", - "version": { - "op": "=", - "number": "10.7" - } - }, - "vendor_id": "0x10de", - "device_id": ["0x0863"], - "features": [ - "accelerated_2d_canvas" - ] - }, - { - "id": 41, - "description": "Disable 3D (but not Stage3D) in Flash on XP", - "cr_bugs": [134885], - "os": { - "type": "win", - "version": { - "op": "=", - "number": "5" - } - }, - "features": [ - "flash_3d" - ] - }, - { - "id": 42, - "description": "AMD Radeon HD 6490M on Snow Leopard is buggy.", - "cr_bugs": [137307], - "os": { - "type": "macosx", - "version": { - "op": "=", - "number": "10.6" - } - }, - "vendor_id": "0x1002", - "device_id": ["0x6760"], - "features": [ - "webgl" - ] - }, - { - "id": 43, - "description": "Intel driver version 8.15.10.1749 has problems sharing textures.", - "cr_bugs": [133924], - "os": { - "type": "win" - }, - "vendor_id": "0x8086", - "driver_version": { - "op": "=", - "number": "8.15.10.1749" - }, - "features": [ - "texture_sharing" - ] - }, - { - "id": 44, - "description": "Intel HD 4000 causes kernel panic on Lion.", - "cr_bugs": [134015], - "os": { - "type": "macosx", - "version": { - "op": "between", - "number": "10.7.0", - "number2": "10.7.4" - } - }, - "vendor_id": "0x8086", - "device_id": ["0x0166"], - "multi_gpu_category": "any", - "features": [ - "all" - ] - }, - { - "id": 45, - "description": "Parallels drivers older than 7 are buggy.", - "cr_bugs": [138105], - "os": { - "type": "win" - }, - "vendor_id": "0x1ab8", - "driver_version": { - "op": "<", - "number": "7" - }, - "features": [ - "all" - ] - }, - { - "id": 46, - "description": "ATI FireMV 2400 cards on Windows are buggy.", - "cr_bugs": [124152], - "os": { - "type": "win" - }, - "vendor_id": "0x1002", - "device_id": ["0x3151"], - "features": [ - "all" - ] - }, - { - "id": 47, - "description": "NVIDIA linux drivers older than 295.* are assumed to be buggy.", - "cr_bugs": [78497], - "os": { - "type": "linux" - }, - "vendor_id": "0x10de", - "driver_vendor": { - "op": "=", - "value": "NVIDIA" - }, - "driver_version": { - "op": "<", - "number": "295" - }, - "features": [ - "all" - ] - }, - { - "id": 48, - // Please keep in sync with content/test/content_browser_test.cc. - "description": "Accelerated video decode is unavailable on Mac and Linux.", - "cr_bugs": [137247, 133828], - "exceptions": [ - { - "os": { - "type": "chromeos" - } - }, - { - "os": { - "type": "win" - } - } - ], - "features": [ - "accelerated_video_decode" - ] - }, - { - "id": 49, - "description": "NVidia GeForce GT 650M can cause the system to hang with flash 3D.", - "cr_bugs": [140175], - "os": { - "type": "macosx", - "version": { - "op": "between", - "number": "10.8.0", - "number2": "10.8.1" - } - }, - "multi_gpu_style": "optimus", - "vendor_id": "0x10de", - "device_id": ["0x0fd5"], - "features": [ - "flash_3d", - "flash_stage3d" - ] - }, - { - "id": 50, - "description": "Disable VMware software renderer.", - "cr_bugs": [145531], - "os": { - "type": "linux" - }, - "gl_vendor": { - "op": "beginwith", - "value": "VMware" - }, - "features": [ - "all" - ] - }, - { - "id": 51, - "description": "NVIDIA drivers 6.14.11.9621 is buggy on Windows XP.", - "cr_bugs": [152096], - "os": { - "type": "win", - "version": { - "op": "=", - "number": "5" - } - }, - "vendor_id": "0x10de", - "driver_version": { - "op": "=", - "number": "6.14.11.9621" - }, - "features": [ - "all" - ] - }, - { - "id": 52, - "description": "NVIDIA drivers 6.14.11.8267 is buggy on Windows XP.", - "cr_bugs": [152096], - "os": { - "type": "win", - "version": { - "op": "=", - "number": "5" - } - }, - "vendor_id": "0x10de", - "driver_version": { - "op": "=", - "number": "6.14.11.8267" - }, - "features": [ - "all" - ] - }, - { - "id": 53, - "description": "The Intel GMA500 is too slow for Stage3D.", - "cr_bugs": [152096], - "vendor_id": "0x8086", - "device_id": ["0x8108", "0x8109"], - "features": [ - "flash_stage3d" - ] - }, - { - "id": 55, - "description": "Drivers older than 2007-01 on Windows are assumed to be buggy.", - "cr_bugs": [72979, 89802], - "os": { - "type": "win" - }, - "driver_date": { - "op": "<", - "number": "2007.1" - }, - "exceptions": [ - { - "vendor_id": "0x8086", - "device_id": ["0x29a2"], - "driver_version": { - "op": ">=", - "number": "7.15.10.1624" - } - } - ], - "features": [ - "all" - ] - }, - { - "id": 56, - "description": "NVIDIA linux drivers are unstable when using multiple Open GL contexts and with low memory.", - "cr_bugs": [145600], - "os": { - "type": "linux" - }, - "vendor_id": "0x10de", - "driver_vendor": { - "op": "=", - "value": "NVIDIA" - }, - "features": [ - "accelerated_video", - "accelerated_video_decode", - "flash_3d", - "flash_stage3d" - ] - }, - { - "id": 57, - "description": "Enable panel fitting capability on ChromeOS only on IVB and SNB Graphics Controllers.", - "exceptions": [ - { - "os": { - "type": "chromeos" - }, - "vendor_id": "0x8086", - "device_id": ["0x0106", "0x0116", "0x0166"] - } - ], - "features": [ - "panel_fitting" - ] - }, - { - "id": 59, - "description": "NVidia driver 8.15.11.8593 is crashy on Windows.", - "cr_bugs": [155749], - "os": { - "type": "win" - }, - "vendor_id": "0x10de", - "driver_version": { - "op": "=", - "number": "8.15.11.8593" - }, - "features": [ - "accelerated_video_decode" - ] - }, - { - "id": 60, - "description": "Multisampling is buggy on Mac with NVIDIA gpu prior to 10.8.3.", - "cr_bugs": [137303], - "os": { - "type": "macosx", - "version": { - "op": "<", - "number": "10.8.3" - } - }, - "vendor_id": "0x10de", - "features": [ - "multisampling" - ] - }, - { - "id": 61, - "description": "Multisampling is buggy on Mac with Intel gpu prior to 10.8.3.", - "cr_bugs": [137303], - "os": { - "type": "macosx", - "version": { - "op": "<", - "number": "10.8.3" - } - }, - "vendor_id": "0x8086", - "features": [ - "multisampling" - ] - }, - { - "id": 62, - "description": "Accelerated 2D canvas buggy on old Qualcomm Adreno.", - "cr_bugs": [161575], - "os": { - "type": "android" - }, - "gl_renderer": { - "op": "contains", - "value": "Adreno" - }, - "driver_version": { - "op": "<", - "number": "4.1" - }, - "features": [ - "accelerated_2d_canvas" - ] - }, - { - "id": 63, - "description": "Multisampling is buggy on Mac with AMD gpu prior to 10.8.3.", - "cr_bugs": [162466], - "os": { - "type": "macosx", - "version": { - "op": "<", - "number": "10.8.3" - } - }, - "vendor_id": "0x1002", - "features": [ - "multisampling" - ] - }, - { - "id": 64, - "description": "Hardware video decode is only supported in win7+.", - "cr_bugs": [159458], - "os": { - "type": "win", - "version": { - "op": "<", - "number": "6.1" - } - }, - "features": [ - "accelerated_video_decode" - ] - }, - { - "id": 65, - "description": "Force compositing mode is unstable in Win Vista.", - "cr_bugs": [170421], - "os": { - "type": "win", - "version": { - "op": "=", - "number": "6.0" - } - }, - "features": [ - "force_compositing_mode" - ] - }, - { - "id": 66, - "description": "Force compositing mode is unstable in MacOSX earlier than 10.8.", - "cr_bugs": [174101], - "os": { - "type": "macosx", - "version": { - "op": "<", - "number": "10.8" - } - }, - "features": [ - "force_compositing_mode" - ] - }, - { - "id": 67, - "description": "Accelerated 2D Canvas is not supported on WinXP.", - "cr_bugs": [175149], - "os": { - "type": "win", - "version": { - "op": "=", - "number": "5" - } - }, - "features": [ - "accelerated_2d_canvas" - ] - }, - { - "id": 68, - "description": "VMware Fusion 4 has corrupt rendering with Win Vista+.", - "cr_bugs": [169470], - "os": { - "type": "win", - "version": { - "op": ">=", - "number": "6.0" - } - }, - "vendor_id": "0x15ad", - "driver_version": { - "op": "<=", - "number": "7.14.1.1134" - }, - "features": [ - "all" - ] - }, - { - "id": 69, - "description": "NVIDIA driver 8.17.11.9621 is buggy with Stage3D baseline mode.", - "cr_bugs": [172771], - "os": { - "type": "win" - }, - "vendor_id": "0x10de", - "driver_version": { - "op": "=", - "number": "8.17.11.9621" - }, - "features": [ - "flash_stage3d_baseline" - ] - }, - { - "id": 70, - "description": "NVIDIA driver 8.17.11.8267 is buggy with Stage3D baseline mode.", - "cr_bugs": [172771], - "os": { - "type": "win" - }, - "vendor_id": "0x10de", - "driver_version": { - "op": "=", - "number": "8.17.11.8267" - }, - "features": [ - "flash_stage3d_baseline" - ] - }, - { - "id": 71, - "description": "All Intel drivers before 8.15.10.2021 are buggy with Stage3D baseline mode.", - "cr_bugs": [172771], - "os": { - "type": "win" - }, - "vendor_id": "0x8086", - "driver_version": { - "op": "<", - "number": "8.15.10.2021" - }, - "features": [ - "flash_stage3d_baseline" - ] - }, - { - "id": 72, - "description": "NVIDIA GeForce 6200 LE is buggy with WebGL.", - "cr_bugs": [232529], - "os": { - "type": "win" - }, - "vendor_id": "0x10de", - "device_id": ["0x0163"], - "features": [ - "webgl" - ] - }, - { - "id": 73, - "description": "WebGL is buggy with the NVIDIA GeForce GT 330M, 9400, and 9400M on MacOSX earlier than 10.8", - "cr_bugs": [233523], - "os": { - "type": "macosx", - "version": { - "op": "<", - "number": "10.8" - } - }, - "vendor_id": "0x10de", - "device_id": ["0x0a29", "0x0861", "0x0863"], - "features": [ - "webgl" - ] - } - ] -} diff --git a/content/browser/gpu/webgl_conformance_test.cc b/content/browser/gpu/webgl_conformance_test.cc index c539f5cedd..3d343786cf 100644 --- a/content/browser/gpu/webgl_conformance_test.cc +++ b/content/browser/gpu/webgl_conformance_test.cc @@ -13,8 +13,8 @@ #include "content/shell/shell.h" #include "content/test/content_browser_test.h" #include "content/test/content_browser_test_utils.h" -#include "content/test/gpu/gpu_test_config.h" -#include "content/test/gpu/gpu_test_expectations_parser.h" +#include "gpu/config/gpu_test_config.h" +#include "gpu/config/gpu_test_expectations_parser.h" #include "net/base/net_util.h" namespace content { @@ -26,6 +26,11 @@ class WebGLConformanceTest : public ContentBrowserTest { virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { // Allow privileged WebGL extensions. command_line->AppendSwitch(switches::kEnablePrivilegedWebGLExtensions); +#if defined(OS_ANDROID) + command_line->AppendSwitch(switches::kEnableExperimentalWebGL); + command_line->AppendSwitch( + switches::kDisableGestureRequirementForMediaPlayback); +#endif } virtual void SetUpInProcessBrowserTestFixture() OVERRIDE { @@ -47,14 +52,18 @@ class WebGLConformanceTest : public ContentBrowserTest { ASSERT_TRUE(bot_config_.IsValid()) << "Invalid bot configuration"; - ASSERT_TRUE(test_expectations_.LoadTestExpectations( - GPUTestExpectationsParser::kWebGLConformanceTest)); + base::FilePath path; + ASSERT_TRUE(PathService::Get(DIR_TEST_DATA, &path)); + path = path.Append(FILE_PATH_LITERAL("gpu")) + .Append(FILE_PATH_LITERAL("webgl_conformance_test_expectations.txt")); + ASSERT_TRUE(file_util::PathExists(path)); + ASSERT_TRUE(test_expectations_.LoadTestExpectations(path)); } void RunTest(std::string url, std::string test_name) { int32 expectation = test_expectations_.GetTestExpectation(test_name, bot_config_); - if (expectation != GPUTestExpectationsParser::kGpuTestPass) { + if (expectation != gpu::GPUTestExpectationsParser::kGpuTestPass) { LOG(WARNING) << "Test " << test_name << " is bypassed"; return; } @@ -71,8 +80,8 @@ class WebGLConformanceTest : public ContentBrowserTest { private: base::FilePath test_path_; - GPUTestBotConfig bot_config_; - GPUTestExpectationsParser test_expectations_; + gpu::GPUTestBotConfig bot_config_; + gpu::GPUTestExpectationsParser test_expectations_; }; #define CONFORMANCE_TEST(name, url) \ diff --git a/content/browser/in_process_webkit/indexed_db_browsertest.cc b/content/browser/in_process_webkit/indexed_db_browsertest.cc index 163cfe6d99..cace63a35d 100644 --- a/content/browser/in_process_webkit/indexed_db_browsertest.cc +++ b/content/browser/in_process_webkit/indexed_db_browsertest.cc @@ -24,7 +24,7 @@ #include "content/shell/shell.h" #include "content/test/content_browser_test.h" #include "content/test/content_browser_test_utils.h" -#include "webkit/database/database_util.h" +#include "webkit/browser/database/database_util.h" #include "webkit/quota/quota_manager.h" using quota::QuotaManager; @@ -406,7 +406,7 @@ IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, ConnectionsClosedOnTabClose) { // Start on a different URL to force a new renderer process. Shell* new_shell = CreateBrowser(); - NavigateToURL(new_shell, GURL(chrome::kAboutBlankURL)); + NavigateToURL(new_shell, GURL(kAboutBlankURL)); NavigateAndWaitForTitle(new_shell, "version_change_blocked.html", "#tab2", "setVersion(3) blocked"); diff --git a/content/browser/in_process_webkit/indexed_db_dispatcher_host.cc b/content/browser/in_process_webkit/indexed_db_dispatcher_host.cc index b6a2a266d5..2398b709d3 100644 --- a/content/browser/in_process_webkit/indexed_db_dispatcher_host.cc +++ b/content/browser/in_process_webkit/indexed_db_dispatcher_host.cc @@ -33,7 +33,7 @@ #include "third_party/WebKit/Source/Platform/chromium/public/WebVector.h" #include "webkit/base/file_path_string_conversions.h" #include "webkit/base/origin_url_conversions.h" -#include "webkit/database/database_util.h" +#include "webkit/browser/database/database_util.h" using webkit_database::DatabaseUtil; using WebKit::WebData; diff --git a/content/browser/indexed_db/indexed_db_context_impl.cc b/content/browser/indexed_db/indexed_db_context_impl.cc index fb6953b6c9..2a958b4112 100644 --- a/content/browser/indexed_db/indexed_db_context_impl.cc +++ b/content/browser/indexed_db/indexed_db_context_impl.cc @@ -23,7 +23,7 @@ #include "third_party/WebKit/Source/Platform/chromium/public/WebString.h" #include "webkit/base/file_path_string_conversions.h" #include "webkit/base/origin_url_conversions.h" -#include "webkit/database/database_util.h" +#include "webkit/browser/database/database_util.h" #include "webkit/quota/quota_manager.h" #include "webkit/quota/special_storage_policy.h" diff --git a/content/browser/indexed_db/indexed_db_quota_client.cc b/content/browser/indexed_db/indexed_db_quota_client.cc index 56635e3a61..25f9668d0f 100644 --- a/content/browser/indexed_db/indexed_db_quota_client.cc +++ b/content/browser/indexed_db/indexed_db_quota_client.cc @@ -11,7 +11,7 @@ #include "content/browser/indexed_db/indexed_db_context_impl.h" #include "content/public/browser/browser_thread.h" #include "net/base/net_util.h" -#include "webkit/database/database_util.h" +#include "webkit/browser/database/database_util.h" using quota::QuotaClient; using webkit_database::DatabaseUtil; @@ -43,10 +43,9 @@ void GetAllOriginsOnWebKitThread( void DidGetOrigins( const IndexedDBQuotaClient::GetOriginsCallback& callback, - const std::set<GURL>* origins, - quota::StorageType storage_type) { + const std::set<GURL>* origins) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - callback.Run(*origins, storage_type); + callback.Run(*origins); } void GetOriginsForHostOnWebKitThread( @@ -114,7 +113,7 @@ void IndexedDBQuotaClient::GetOriginsForType( // All databases are in the temp namespace for now. if (type != quota::kStorageTypeTemporary) { - callback.Run(std::set<GURL>(), type); + callback.Run(std::set<GURL>()); return; } @@ -126,8 +125,7 @@ void IndexedDBQuotaClient::GetOriginsForType( base::Unretained(origins_to_return)), base::Bind(&DidGetOrigins, callback, - base::Owned(origins_to_return), - type)); + base::Owned(origins_to_return))); } void IndexedDBQuotaClient::GetOriginsForHost( @@ -139,7 +137,7 @@ void IndexedDBQuotaClient::GetOriginsForHost( // All databases are in the temp namespace for now. if (type != quota::kStorageTypeTemporary) { - callback.Run(std::set<GURL>(), type); + callback.Run(std::set<GURL>()); return; } @@ -152,8 +150,7 @@ void IndexedDBQuotaClient::GetOriginsForHost( base::Unretained(origins_to_return)), base::Bind(&DidGetOrigins, callback, - base::Owned(origins_to_return), - type)); + base::Owned(origins_to_return))); } void IndexedDBQuotaClient::DeleteOriginData( diff --git a/content/browser/indexed_db/indexed_db_quota_client_unittest.cc b/content/browser/indexed_db/indexed_db_quota_client_unittest.cc index 2570f9de75..0d8628ac71 100644 --- a/content/browser/indexed_db/indexed_db_quota_client_unittest.cc +++ b/content/browser/indexed_db/indexed_db_quota_client_unittest.cc @@ -89,7 +89,6 @@ class IndexedDBQuotaClientTest : public testing::Test { quota::QuotaClient* client, quota::StorageType type) { origins_.clear(); - type_ = quota::kStorageTypeTemporary; client->GetOriginsForType( type, base::Bind(&IndexedDBQuotaClientTest::OnGetOriginsComplete, @@ -103,7 +102,6 @@ class IndexedDBQuotaClientTest : public testing::Test { quota::StorageType type, const std::string& host) { origins_.clear(); - type_ = quota::kStorageTypeTemporary; client->GetOriginsForHost( type, host, base::Bind(&IndexedDBQuotaClientTest::OnGetOriginsComplete, @@ -147,10 +145,8 @@ class IndexedDBQuotaClientTest : public testing::Test { usage_ = usage; } - void OnGetOriginsComplete(const std::set<GURL>& origins, - quota::StorageType type) { + void OnGetOriginsComplete(const std::set<GURL>& origins) { origins_ = origins; - type_ = type; } void OnDeleteOriginComplete(quota::QuotaStatusCode code) { @@ -160,7 +156,6 @@ class IndexedDBQuotaClientTest : public testing::Test { base::ScopedTempDir temp_dir_; int64 usage_; std::set<GURL> origins_; - quota::StorageType type_; scoped_refptr<IndexedDBContextImpl> idb_context_; base::WeakPtrFactory<IndexedDBQuotaClientTest> weak_factory_; base::MessageLoop message_loop_; diff --git a/content/browser/loader/redirect_to_file_resource_handler.cc b/content/browser/loader/redirect_to_file_resource_handler.cc index b82438bf55..12bd979310 100644 --- a/content/browser/loader/redirect_to_file_resource_handler.cc +++ b/content/browser/loader/redirect_to_file_resource_handler.cc @@ -17,7 +17,7 @@ #include "net/base/io_buffer.h" #include "net/base/mime_sniffer.h" #include "net/base/net_errors.h" -#include "webkit/blob/shareable_file_reference.h" +#include "webkit/common/blob/shareable_file_reference.h" using webkit_blob::ShareableFileReference; diff --git a/content/browser/loader/resource_dispatcher_host_browsertest.cc b/content/browser/loader/resource_dispatcher_host_browsertest.cc index 43cb267666..2cb1124ad9 100644 --- a/content/browser/loader/resource_dispatcher_host_browsertest.cc +++ b/content/browser/loader/resource_dispatcher_host_browsertest.cc @@ -20,7 +20,9 @@ #include "content/test/net/url_request_failed_job.h" #include "content/test/net/url_request_mock_http_job.h" #include "net/base/net_errors.h" -#include "net/test/spawned_test_server/spawned_test_server.h" +#include "net/test/embedded_test_server/embedded_test_server.h" +#include "net/test/embedded_test_server/http_response.h" +#include "net/test/embedded_test_server/http_request.h" namespace content { @@ -88,9 +90,9 @@ class ResourceDispatcherHostBrowserTest : public ContentBrowserTest, // Test title for content created by javascript window.open(). // See http://crbug.com/5988 IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest, DynamicTitle1) { - ASSERT_TRUE(test_server()->Start()); + ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); - GURL url(test_server()->GetURL("files/dynamic1.html")); + GURL url(embedded_test_server()->GetURL("/dynamic1.html")); string16 title; ASSERT_TRUE(GetPopupTitle(url, &title)); EXPECT_TRUE(StartsWith(title, ASCIIToUTF16("My Popup Title"), true)) @@ -100,9 +102,9 @@ IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest, DynamicTitle1) { // Test title for content created by javascript window.open(). // See http://crbug.com/5988 IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest, DynamicTitle2) { - ASSERT_TRUE(test_server()->Start()); + ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); - GURL url(test_server()->GetURL("files/dynamic2.html")); + GURL url(embedded_test_server()->GetURL("/dynamic2.html")); string16 title; ASSERT_TRUE(GetPopupTitle(url, &title)); EXPECT_TRUE(StartsWith(title, ASCIIToUTF16("My Dynamic Title"), true)) @@ -156,9 +158,9 @@ IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest, // Test for bug #1091358. IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest, SyncXMLHttpRequest) { - ASSERT_TRUE(test_server()->Start()); + ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); NavigateToURL( - shell(), test_server()->GetURL("files/sync_xmlhttprequest.html")); + shell(), embedded_test_server()->GetURL("/sync_xmlhttprequest.html")); // Let's check the XMLHttpRequest ran successfully. bool success = false; @@ -172,10 +174,10 @@ IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest, SyncXMLHttpRequest) { // If this flakes, use http://crbug.com/62776. IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest, SyncXMLHttpRequest_Disallowed) { - ASSERT_TRUE(test_server()->Start()); + ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); NavigateToURL( shell(), - test_server()->GetURL("files/sync_xmlhttprequest_disallowed.html")); + embedded_test_server()->GetURL("/sync_xmlhttprequest_disallowed.html")); // Let's check the XMLHttpRequest ran successfully. bool success = false; @@ -192,18 +194,18 @@ IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest, // If this flakes, use http://crbug.com/56264. IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest, SyncXMLHttpRequest_DuringUnload) { - ASSERT_TRUE(test_server()->Start()); + ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); BrowserContext::GetDownloadManager( shell()->web_contents()->GetBrowserContext())->AddObserver(this); CheckTitleTest( - test_server()->GetURL("files/sync_xmlhttprequest_during_unload.html"), + embedded_test_server()->GetURL("/sync_xmlhttprequest_during_unload.html"), "sync xhr on unload"); // Navigate to a new page, to dispatch unload event and trigger xhr. // (the bug would make this step hang the renderer). CheckTitleTest( - test_server()->GetURL("files/title2.html"), "Title Of Awesomeness"); + embedded_test_server()->GetURL("/title2.html"), "Title Of Awesomeness"); ASSERT_FALSE(got_downloads()); } @@ -211,9 +213,9 @@ IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest, // Tests that onunload is run for cross-site requests. (Bug 1114994) IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest, CrossSiteOnunloadCookie) { - ASSERT_TRUE(test_server()->Start()); + ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); - GURL url = test_server()->GetURL("files/onunload_cookie.html"); + GURL url = embedded_test_server()->GetURL("/onunload_cookie.html"); CheckTitleTest(url, "set cookie on unload"); // Navigate to a new cross-site page, to dispatch unload event and set the @@ -230,9 +232,9 @@ IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest, // without network loads (e.g., about:blank, data URLs). IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest, DISABLED_CrossSiteImmediateLoadOnunloadCookie) { - ASSERT_TRUE(test_server()->Start()); + ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); - GURL url = test_server()->GetURL("files/onunload_cookie.html"); + GURL url = embedded_test_server()->GetURL("/onunload_cookie.html"); CheckTitleTest(url, "set cookie on unload"); // Navigate to a cross-site page that loads immediately without making a @@ -243,18 +245,38 @@ IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest, EXPECT_EQ("onunloadCookie=foo", GetCookies(url)); } +namespace { + +// Handles |request| by serving a redirect response. +scoped_ptr<net::test_server::HttpResponse> NoContentResponseHandler( + const std::string& path, + const net::test_server::HttpRequest& request) { + if (!StartsWithASCII(path, request.relative_url, true)) + return scoped_ptr<net::test_server::HttpResponse>(NULL); + + scoped_ptr<net::test_server::BasicHttpResponse> http_response( + new net::test_server::BasicHttpResponse); + http_response->set_code(net::test_server::NO_CONTENT); + return http_response.PassAs<net::test_server::HttpResponse>(); +} + +} // namespace + // Tests that the unload handler is not run for 204 responses. // If this flakes use http://crbug.com/80596. IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest, CrossSiteNoUnloadOn204) { - ASSERT_TRUE(test_server()->Start()); + ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); // Start with a URL that sets a cookie in its unload handler. - GURL url = test_server()->GetURL("files/onunload_cookie.html"); + GURL url = embedded_test_server()->GetURL("/onunload_cookie.html"); CheckTitleTest(url, "set cookie on unload"); // Navigate to a cross-site URL that returns a 204 No Content response. - NavigateToURL(shell(), test_server()->GetURL("nocontent")); + const char kNoContentPath[] = "/nocontent"; + embedded_test_server()->RegisterRequestHandler( + base::Bind(&NoContentResponseHandler, kNoContentPath)); + NavigateToURL(shell(), embedded_test_server()->GetURL(kNoContentPath)); // Check that the unload cookie was not set. EXPECT_EQ("", GetCookies(url)); @@ -305,9 +327,9 @@ IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest, // Flaky: http://crbug.com/100823 IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest, CrossSiteNavigationErrorPage) { - ASSERT_TRUE(test_server()->Start()); + ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); - GURL url(test_server()->GetURL("files/onunload_cookie.html")); + GURL url(embedded_test_server()->GetURL("/onunload_cookie.html")); CheckTitleTest(url, "set cookie on unload"); // Navigate to a new cross-site URL that results in an error. @@ -337,7 +359,7 @@ IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest, TitleWatcher title_watcher(shell()->web_contents(), expected_title16); bool success; - GURL test_url(test_server()->GetURL("files/title2.html")); + GURL test_url(embedded_test_server()->GetURL("/title2.html")); std::string redirect_script = "window.location='" + test_url.possibly_invalid_spec() + "';" + "window.domAutomationController.send(true);"; @@ -350,9 +372,9 @@ IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest, IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest, CrossSiteNavigationErrorPage2) { - ASSERT_TRUE(test_server()->Start()); + ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); - GURL url(test_server()->GetURL("files/title2.html")); + GURL url(embedded_test_server()->GetURL("/title2.html")); CheckTitleTest(url, "Title Of Awesomeness"); // Navigate to a new cross-site URL that results in an error. diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc index 89a473eb56..d5239bc50f 100644 --- a/content/browser/loader/resource_dispatcher_host_impl.cc +++ b/content/browser/loader/resource_dispatcher_host_impl.cc @@ -86,8 +86,8 @@ #include "net/url_request/url_request_job_factory.h" #include "webkit/appcache/appcache_interceptor.h" #include "webkit/appcache/appcache_interfaces.h" -#include "webkit/blob/blob_storage_controller.h" -#include "webkit/blob/shareable_file_reference.h" +#include "webkit/browser/blob/blob_storage_controller.h" +#include "webkit/common/blob/shareable_file_reference.h" #include "webkit/glue/resource_request_body.h" #include "webkit/glue/webkit_glue.h" @@ -612,7 +612,8 @@ ResourceDispatcherHostImpl::MaybeInterceptAsStream(net::URLRequest* request, info->GetChildID(), info->GetRouteID(), target_id, - handler->stream()->CreateHandle(request->url(), mime_type)); + handler->stream()->CreateHandle(request->url(), mime_type), + request->GetExpectedContentSize()); return (scoped_ptr<ResourceHandler>(handler.release())).Pass(); } @@ -724,10 +725,17 @@ void ResourceDispatcherHostImpl::DidReceiveResponse(ResourceLoader* loader) { ResourceRequestInfoImpl* info = loader->GetRequestInfo(); // There should be an entry in the map created when we dispatched the // request. - GlobalRoutingID routing_id(info->GetGlobalRoutingID()); - DCHECK(offline_policy_map_.end() != offline_policy_map_.find(routing_id)); - offline_policy_map_[routing_id]->UpdateStateForSuccessfullyStartedRequest( - loader->request()->response_info()); + OfflineMap::iterator policy_it( + offline_policy_map_.find(info->GetGlobalRoutingID())); + if (offline_policy_map_.end() != policy_it) { + policy_it->second->UpdateStateForSuccessfullyStartedRequest( + loader->request()->response_info()); + } else { + // We should always have an entry in offline_policy_map_ from when + // this request traversed Begin{Download,SaveFile,Request}. + // TODO(rdsmith): This isn't currently true; see http://crbug.com/241176. + NOTREACHED(); + } int render_process_id, render_view_id; if (!info->GetAssociatedRenderView(&render_process_id, &render_view_id)) diff --git a/content/browser/loader/resource_message_filter.cc b/content/browser/loader/resource_message_filter.cc index 47e86d5163..7c523975fb 100644 --- a/content/browser/loader/resource_message_filter.cc +++ b/content/browser/loader/resource_message_filter.cc @@ -8,7 +8,7 @@ #include "content/browser/fileapi/chrome_blob_storage_context.h" #include "content/browser/loader/resource_dispatcher_host_impl.h" #include "content/public/browser/resource_context.h" -#include "webkit/fileapi/file_system_context.h" +#include "webkit/browser/fileapi/file_system_context.h" namespace content { diff --git a/content/browser/loader/resource_request_info_impl.cc b/content/browser/loader/resource_request_info_impl.cc index 09b82cab1c..51e39ff3dd 100644 --- a/content/browser/loader/resource_request_info_impl.cc +++ b/content/browser/loader/resource_request_info_impl.cc @@ -9,7 +9,7 @@ #include "content/common/net/url_request_user_data.h" #include "content/public/browser/global_request_id.h" #include "net/url_request/url_request.h" -#include "webkit/blob/blob_data.h" +#include "webkit/common/blob/blob_data.h" namespace content { diff --git a/content/browser/media/encrypted_media_browsertest.cc b/content/browser/media/encrypted_media_browsertest.cc index 34cbd65376..e2f6848942 100644 --- a/content/browser/media/encrypted_media_browsertest.cc +++ b/content/browser/media/encrypted_media_browsertest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -27,17 +27,17 @@ #include <gnu/libc-version.h> #endif // defined(WIDEVINE_CDM_AVAILABLE) && defined(OS_LINUX) +#if defined(ENABLE_PEPPER_CDMS) // Platform-specific filename relative to the chrome executable. -#if defined(OS_WIN) -static const char kClearKeyLibraryName[] = "clearkeycdmadapter.dll"; -static const char kWidevineLibraryName[] = "widevinecdmadapter.dll"; -#elif defined(OS_MACOSX) -static const char kClearKeyLibraryName[] = "clearkeycdmadapter.plugin"; -static const char kWidevineLibraryName[] = "widevinecdmadapter.plugin"; +static const char kClearKeyCdmAdapterFileName[] = +#if defined(OS_MACOSX) + "clearkeycdmadapter.plugin"; +#elif defined(OS_WIN) + "clearkeycdmadapter.dll"; #elif defined(OS_POSIX) -static const char kClearKeyLibraryName[] = "libclearkeycdmadapter.so"; -static const char kWidevineLibraryName[] = "libwidevinecdmadapter.so"; + "libclearkeycdmadapter.so"; #endif +#endif // defined(ENABLE_PEPPER_CDMS) // Available key systems. static const char kClearKeyKeySystem[] = "webkit-org.w3.clearkey"; @@ -52,8 +52,10 @@ static const char kMP4AudioOnly[] = "audio/mp4; codecs=\"mp4a.40.2\""; static const char kMP4VideoOnly[] = "video/mp4; codecs=\"avc1.4D4041\""; // Common test expectations. -const string16 kExpectedEnded = ASCIIToUTF16("ENDED"); -const string16 kExpectedWebKitError = ASCIIToUTF16("WEBKITKEYERROR"); +const string16 kEnded = ASCIIToUTF16("ENDED"); +const string16 kError = ASCIIToUTF16("ERROR"); +const string16 kFailed = ASCIIToUTF16("FAILED"); +const string16 kKeyError = ASCIIToUTF16("KEYERROR"); namespace content { @@ -79,9 +81,6 @@ class EncryptedMediaTest : public testing::WithParamInterface<const char*>, const string16 expectation) { // TODO(shadi): Add non-HTTP tests once src is supported for EME. ASSERT_TRUE(test_server()->Start()); - - const string16 kError = ASCIIToUTF16("ERROR"); - const string16 kFailed = ASCIIToUTF16("FAILED"); GURL player_gurl = test_server()->GetURL(base::StringPrintf( "files/media/%s?keysystem=%s&mediafile=%s&mediatype=%s", html_page, key_system, media_file, media_type)); @@ -105,34 +104,31 @@ class EncryptedMediaTest : public testing::WithParamInterface<const char*>, } protected: - // Registers any CDM plugins not registered by default. +#if defined(ENABLE_PEPPER_CDMS) virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { - RegisterPepperPlugin(command_line, kClearKeyLibraryName, - kExternalClearKeyKeySystem); + RegisterPepperCdm(command_line, kClearKeyCdmAdapterFileName, + kExternalClearKeyKeySystem); } - virtual void RegisterPepperPlugin(CommandLine* command_line, - const std::string& library_name, - const std::string& key_system) { + virtual void RegisterPepperCdm(CommandLine* command_line, + const std::string& adapter_name, + const std::string& key_system) { // Append the switch to register the Clear Key CDM Adapter. base::FilePath plugin_dir; EXPECT_TRUE(PathService::Get(base::DIR_MODULE, &plugin_dir)); -#if defined(OS_WIN) - base::FilePath plugin_lib = plugin_dir.Append(ASCIIToWide(library_name)); -#else - base::FilePath plugin_lib = plugin_dir.Append(library_name); -#endif + base::FilePath plugin_lib = plugin_dir.AppendASCII(adapter_name); EXPECT_TRUE(file_util::PathExists(plugin_lib)); base::FilePath::StringType pepper_plugin = plugin_lib.value(); pepper_plugin.append(FILE_PATH_LITERAL("#CDM#0.1.0.0;")); #if defined(OS_WIN) - pepper_plugin.append(ASCIIToWide(webkit_media::GetPluginType(key_system))); + pepper_plugin.append(ASCIIToWide(webkit_media::GetPepperType(key_system))); #else - pepper_plugin.append(webkit_media::GetPluginType(key_system)); + pepper_plugin.append(webkit_media::GetPepperType(key_system)); #endif command_line->AppendSwitchNative(switches::kRegisterPepperPlugins, pepper_plugin); } +#endif // defined(ENABLE_PEPPER_CDMS) }; #if defined(WIDEVINE_CDM_AVAILABLE) @@ -155,7 +151,7 @@ class WVEncryptedMediaTest : public EncryptedMediaTest { } #endif // defined(OS_LINUX) EncryptedMediaTest::TestSimplePlayback(encrypted_media, media_type, - key_system, kExpectedWebKitError); + key_system, kKeyError); bool receivedKeyMessage = false; EXPECT_TRUE(ExecuteScriptAndExtractBool( shell()->web_contents(), @@ -165,20 +161,23 @@ class WVEncryptedMediaTest : public EncryptedMediaTest { } protected: - // Registers any CDM plugins not registered by default. +#if defined(ENABLE_PEPPER_CDMS) virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { - command_line->AppendSwitch(switches::kAllowFileAccessFromFiles); - RegisterPepperPlugin(command_line, kWidevineLibraryName, - kWidevineKeySystem); + RegisterPepperCdm(command_line, kWidevineCdmAdapterFileName, + kWidevineKeySystem); } +#endif // defined(ENABLE_PEPPER_CDMS) }; #endif // defined(WIDEVINE_CDM_AVAILABLE) INSTANTIATE_TEST_CASE_P(ClearKey, EncryptedMediaTest, ::testing::Values(kClearKeyKeySystem)); +// External Clear Key is currently only used on platforms that use Pepper CDMs. +#if defined(ENABLE_PEPPER_CDMS) INSTANTIATE_TEST_CASE_P(ExternalClearKey, EncryptedMediaTest, ::testing::Values(kExternalClearKeyKeySystem)); +#endif IN_PROC_BROWSER_TEST_F(EncryptedMediaTest, InvalidKeySystem) { const string16 kExpected = ASCIIToUTF16( @@ -188,28 +187,27 @@ IN_PROC_BROWSER_TEST_F(EncryptedMediaTest, InvalidKeySystem) { } IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, Playback_AudioOnly_WebM) { - TestSimplePlayback("bear-a-enc_a.webm", kWebMAudioOnly, GetParam(), - kExpectedEnded); + TestSimplePlayback("bear-a-enc_a.webm", kWebMAudioOnly, GetParam(), kEnded); } IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, Playback_AudioClearVideo_WebM) { TestSimplePlayback("bear-320x240-av-enc_a.webm", kWebMAudioVideo, GetParam(), - kExpectedEnded); + kEnded); } IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, Playback_VideoAudio_WebM) { TestSimplePlayback("bear-320x240-av-enc_av.webm", kWebMAudioVideo, GetParam(), - kExpectedEnded); + kEnded); } IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, Playback_VideoOnly_WebM) { TestSimplePlayback("bear-320x240-v-enc_v.webm", kWebMVideoOnly, GetParam(), - kExpectedEnded); + kEnded); } IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, Playback_VideoClearAudio_WebM) { TestSimplePlayback("bear-320x240-av-enc_v.webm", kWebMAudioVideo,GetParam(), - kExpectedEnded); + kEnded); } IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, FrameChangeVideo) { @@ -218,18 +216,18 @@ IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, FrameChangeVideo) { if (base::win::GetVersion() < base::win::VERSION_VISTA) return; #endif - TestFrameSizeChange(GetParam(), kExpectedEnded); + TestFrameSizeChange(GetParam(), kEnded); } #if defined(GOOGLE_CHROME_BUILD) || defined(USE_PROPRIETARY_CODECS) IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, Playback_VideoOnly_MP4) { TestSimplePlayback("bear-640x360-v_frag-cenc.mp4", kMP4VideoOnly, GetParam(), - kExpectedEnded); + kEnded); } IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, Playback_AudioOnly_MP4) { TestSimplePlayback("bear-640x360-a_frag-cenc.mp4", kMP4AudioOnly, GetParam(), - kExpectedEnded); + kEnded); } #endif diff --git a/content/browser/media/media_source_browsertest.cc b/content/browser/media/media_source_browsertest.cc new file mode 100644 index 0000000000..43525b2516 --- /dev/null +++ b/content/browser/media/media_source_browsertest.cc @@ -0,0 +1,85 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/basictypes.h" +#include "base/command_line.h" +#include "base/string16.h" +#include "base/string_util.h" +#include "base/stringprintf.h" +#include "base/utf_string_conversions.h" +#include "content/public/common/content_switches.h" +#include "content/public/test/browser_test_utils.h" +#include "content/shell/shell.h" +#include "content/test/content_browser_test_utils.h" +#include "content/test/layout_browsertest.h" +#include "googleurl/src/gurl.h" + +// Common media types. +static const char kWebMAudioOnly[] = "audio/webm; codecs=\"vorbis\""; +static const char kWebMVideoOnly[] = "video/webm; codecs=\"vp8\""; +static const char kWebMAudioVideo[] = "video/webm; codecs=\"vorbis, vp8\""; + +// Common test expectations. +const string16 kEnded = ASCIIToUTF16("ENDED"); +const string16 kError = ASCIIToUTF16("ERROR"); +const string16 kFailed = ASCIIToUTF16("FAILED"); + +namespace content { + +class MediaSourceTest : public ContentBrowserTest { + public: + void TestSimplePlayback(const char* media_file, const char* media_type, + const string16 expectation) { + ASSERT_NO_FATAL_FAILURE( + RunTest("media_source_player.html", media_file, media_type, + expectation)); + } + + void RunTest(const char* html_page, const char* media_file, + const char* media_type, const string16 expectation) { + ASSERT_TRUE(test_server()->Start()); + GURL player_gurl = test_server()->GetURL(base::StringPrintf( + "files/media/%s?mediafile=%s&mediatype=%s", html_page, media_file, + media_type)); + TitleWatcher title_watcher(shell()->web_contents(), expectation); + title_watcher.AlsoWaitForTitle(kError); + title_watcher.AlsoWaitForTitle(kFailed); + + NavigateToURL(shell(), player_gurl); + string16 final_title = title_watcher.WaitAndGetTitle(); + EXPECT_EQ(expectation, final_title); + + if (final_title == kFailed) { + std::string fail_message; + EXPECT_TRUE(ExecuteScriptAndExtractString( + shell()->web_contents(), + "window.domAutomationController.send(failMessage);", + &fail_message)); + LOG(INFO) << "Test failed: " << fail_message; + } + } +}; + +IN_PROC_BROWSER_TEST_F(MediaSourceTest, Playback_VideoAudio_WebM) { + TestSimplePlayback("bear-320x240.webm", kWebMAudioVideo, kEnded); +} + +IN_PROC_BROWSER_TEST_F(MediaSourceTest, Playback_VideoOnly_WebM) { + TestSimplePlayback("bear-320x240-video-only.webm", kWebMVideoOnly, kEnded); +} + +IN_PROC_BROWSER_TEST_F(MediaSourceTest, Playback_AudioOnly_WebM) { + TestSimplePlayback("bear-320x240-audio-only.webm", kWebMAudioOnly, kEnded); +} + +IN_PROC_BROWSER_TEST_F(MediaSourceTest, Playback_Type_Error) { + TestSimplePlayback("bear-320x240-video-only.webm", kWebMAudioOnly, kError); +} + +IN_PROC_BROWSER_TEST_F(MediaSourceTest, DISABLED_ConfigChangeVideo) { + ASSERT_NO_FATAL_FAILURE( + RunTest("mse_config_change.html", NULL, NULL, kEnded)); +} + +} // namespace content
\ No newline at end of file diff --git a/content/browser/media/webrtc_browsertest.cc b/content/browser/media/webrtc_browsertest.cc index fcd6ad8e85..7c99007f77 100644 --- a/content/browser/media/webrtc_browsertest.cc +++ b/content/browser/media/webrtc_browsertest.cc @@ -10,7 +10,7 @@ #include "content/shell/shell.h" #include "content/test/content_browser_test.h" #include "content/test/content_browser_test_utils.h" -#include "net/test/spawned_test_server/spawned_test_server.h" +#include "net/test/embedded_test_server/embedded_test_server.h" #if defined(OS_WIN) #include "base/win/windows_version.h" @@ -29,8 +29,9 @@ class WebrtcBrowserTest: public ContentBrowserTest { ASSERT_TRUE(CommandLine::ForCurrentProcess()->HasSwitch( switches::kUseFakeDeviceForMediaStream)); - ASSERT_TRUE(test_server()->Start()); + ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); } + protected: bool ExecuteJavascript(const std::string& javascript) { return ExecuteScript(shell()->web_contents(), javascript); @@ -47,7 +48,7 @@ class WebrtcBrowserTest: public ContentBrowserTest { // see that the success callback is called. If the error callback is called or // none of the callbacks are called the tests will simply time out and fail. IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, GetVideoStreamAndStop) { - GURL url(test_server()->GetURL("files/media/getusermedia.html")); + GURL url(embedded_test_server()->GetURL("/media/getusermedia.html")); NavigateToURL(shell(), url); EXPECT_TRUE(ExecuteJavascript("getUserMedia({video: true});")); @@ -56,7 +57,7 @@ IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, GetVideoStreamAndStop) { } IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, GetAudioAndVideoStreamAndStop) { - GURL url(test_server()->GetURL("files/media/getusermedia.html")); + GURL url(embedded_test_server()->GetURL("/media/getusermedia.html")); NavigateToURL(shell(), url); EXPECT_TRUE(ExecuteJavascript("getUserMedia({video: true, audio: true});")); @@ -65,7 +66,7 @@ IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, GetAudioAndVideoStreamAndStop) { } IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, GetAudioAndVideoStreamAndClone) { - GURL url(test_server()->GetURL("files/media/getusermedia.html")); + GURL url(embedded_test_server()->GetURL("/media/getusermedia.html")); NavigateToURL(shell(), url); EXPECT_TRUE(ExecuteJavascript("getUserMediaAndClone();")); @@ -84,7 +85,7 @@ IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, GetAudioAndVideoStreamAndClone) { // These tests will make a complete PeerConnection-based call and verify that // video is playing for the call. IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, MAYBE_CanSetupVideoCall) { - GURL url(test_server()->GetURL("files/media/peerconnection-call.html")); + GURL url(embedded_test_server()->GetURL("/media/peerconnection-call.html")); NavigateToURL(shell(), url); EXPECT_TRUE(ExecuteJavascript("call({video: true});")); @@ -99,7 +100,7 @@ IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, MAYBE_CanSetupVideoCall) { #endif IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, MAYBE_CanSetupAudioAndVideoCall) { - GURL url(test_server()->GetURL("files/media/peerconnection-call.html")); + GURL url(embedded_test_server()->GetURL("/media/peerconnection-call.html")); NavigateToURL(shell(), url); EXPECT_TRUE(ExecuteJavascript("call({video: true, audio: true});")); @@ -107,7 +108,7 @@ IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, MAYBE_CanSetupAudioAndVideoCall) { } IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, MANUAL_CanSetupCallAndSendDtmf) { - GURL url(test_server()->GetURL("files/media/peerconnection-call.html")); + GURL url(embedded_test_server()->GetURL("/media/peerconnection-call.html")); NavigateToURL(shell(), url); EXPECT_TRUE( @@ -117,7 +118,7 @@ IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, MANUAL_CanSetupCallAndSendDtmf) { // TODO(miu): Test is flaky. http://crbug.com/236102 IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, DISABLED_CanMakeEmptyCallThenAddStreamsAndRenegotiate) { - GURL url(test_server()->GetURL("files/media/peerconnection-call.html")); + GURL url(embedded_test_server()->GetURL("/media/peerconnection-call.html")); NavigateToURL(shell(), url); const char* kJavascript = @@ -145,7 +146,7 @@ IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, #endif IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, MAYBE_CanSetupAudioAndVideoCallWithoutMsidAndBundle) { - GURL url(test_server()->GetURL("files/media/peerconnection-call.html")); + GURL url(embedded_test_server()->GetURL("/media/peerconnection-call.html")); NavigateToURL(shell(), url); EXPECT_TRUE(ExecuteJavascript("callWithoutMsidAndBundle();")); @@ -155,7 +156,7 @@ IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, // This test will make a PeerConnection-based call and test an unreliable text // dataChannel. IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, CallWithDataOnly) { - GURL url(test_server()->GetURL("files/media/peerconnection-call.html")); + GURL url(embedded_test_server()->GetURL("/media/peerconnection-call.html")); NavigateToURL(shell(), url); EXPECT_TRUE(ExecuteJavascript("callWithDataOnly();")); @@ -172,7 +173,7 @@ IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, CallWithDataOnly) { // This test will make a PeerConnection-based call and test an unreliable text // dataChannel and audio and video tracks. IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, MAYBE_CallWithDataAndMedia) { - GURL url(test_server()->GetURL("files/media/peerconnection-call.html")); + GURL url(embedded_test_server()->GetURL("/media/peerconnection-call.html")); NavigateToURL(shell(), url); EXPECT_TRUE(ExecuteJavascript("callWithDataAndMedia();")); @@ -182,7 +183,7 @@ IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, MAYBE_CallWithDataAndMedia) { // This test will make a PeerConnection-based call and test an unreliable text // dataChannel and later add an audio and video track. IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, CallWithDataAndLaterAddMedia) { - GURL url(test_server()->GetURL("files/media/peerconnection-call.html")); + GURL url(embedded_test_server()->GetURL("/media/peerconnection-call.html")); NavigateToURL(shell(), url); EXPECT_TRUE(ExecuteJavascript("callWithDataAndLaterAddMedia();")); @@ -200,7 +201,7 @@ IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, CallWithDataAndLaterAddMedia) { // MediaStream that has been created based on a MediaStream created with // getUserMedia. IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, MAYBE_CallWithNewVideoMediaStream) { - GURL url(test_server()->GetURL("files/media/peerconnection-call.html")); + GURL url(embedded_test_server()->GetURL("/media/peerconnection-call.html")); NavigateToURL(shell(), url); EXPECT_TRUE(ExecuteJavascript("callWithNewVideoMediaStream();")); @@ -214,7 +215,7 @@ IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, MAYBE_CallWithNewVideoMediaStream) { // TODO(phoglund): This test is manual since not all buildbots has an audio // input. IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, MANUAL_CallAndModifyStream) { - GURL url(test_server()->GetURL("files/media/peerconnection-call.html")); + GURL url(embedded_test_server()->GetURL("/media/peerconnection-call.html")); NavigateToURL(shell(), url); EXPECT_TRUE( diff --git a/content/browser/media/webrtc_internals_browsertest.cc b/content/browser/media/webrtc_internals_browsertest.cc index 48ade9a3e4..46b513f052 100644 --- a/content/browser/media/webrtc_internals_browsertest.cc +++ b/content/browser/media/webrtc_internals_browsertest.cc @@ -3,14 +3,16 @@ // found in the LICENSE file. #include "base/command_line.h" +#include "base/json/json_reader.h" #include "base/time.h" #include "base/utf_string_conversions.h" +#include "base/values.h" #include "content/public/common/content_switches.h" #include "content/public/test/browser_test_utils.h" #include "content/shell/shell.h" #include "content/test/content_browser_test.h" #include "content/test/content_browser_test_utils.h" -#include "net/test/spawned_test_server/spawned_test_server.h" +#include "net/test/embedded_test_server/embedded_test_server.h" using std::string; namespace content { @@ -126,8 +128,6 @@ class WebRTCInternalsBrowserTest: public ContentBrowserTest { // assume this switch is set by default in content_browsertests. ASSERT_TRUE(CommandLine::ForCurrentProcess()->HasSwitch( switches::kUseFakeDeviceForMediaStream)); - - ASSERT_TRUE(test_server()->Start()); } protected: @@ -272,34 +272,34 @@ class WebRTCInternalsBrowserTest: public ContentBrowserTest { for (stats_iter = stream_iter->second.begin(); stats_iter != stream_iter->second.end(); stats_iter++) { - string graph_id = pc.getIdString() + "-" + - stream_iter->first + "-" + stats_iter->first; + string graph_id = stream_iter->first + "-" + stats_iter->first; for (size_t i = 0; i < stats_iter->second.size(); ++i) { float number; std::stringstream stream(stats_iter->second[i]); stream >> number; if (stream.fail()) continue; - VerifyGraphDataPoint(graph_id, i, stats_iter->second[i]); + VerifyGraphDataPoint( + pc.getIdString(), graph_id, i, stats_iter->second[i]); } } } } // Verifies that the graph data point at index |index| has value |value|. - void VerifyGraphDataPoint( - const string& graph_id, int index, const string& value) { + void VerifyGraphDataPoint(const string& pc_id, const string& graph_id, + int index, const string& value) { bool result = false; ASSERT_TRUE(ExecuteScriptAndExtractBool( shell()->web_contents(), "window.domAutomationController.send(" - "graphViews['" + graph_id + "'] != null)", + "graphViews['" + pc_id + "-" + graph_id + "'] != null)", &result)); EXPECT_TRUE(result); std::stringstream ss; - ss << "var dp = dataSeries['" << graph_id << "']" - ".dataPoints_[" << index << "];" + ss << "var dp = peerConnectionDataStore['" << pc_id << "']" + ".getDataSeries('" << graph_id << "').dataPoints_[" << index << "];" "window.domAutomationController.send(dp.value.toString())"; string actual_value; ASSERT_TRUE(ExecuteScriptAndExtractString( @@ -328,6 +328,65 @@ class WebRTCInternalsBrowserTest: public ContentBrowserTest { &count)); return count; } + + // Verifies |dump| contains |peer_connection_number| peer connection dumps, + // each containing |update_number| updates and |stats_number| stats tables. + void VerifyPageDumpStructure(Value* dump, + int peer_connection_number, + int update_number, + int stats_number) { + EXPECT_NE((Value*)NULL, dump); + EXPECT_EQ(Value::TYPE_DICTIONARY, dump->GetType()); + + DictionaryValue* dict_dump = static_cast<DictionaryValue*>(dump); + EXPECT_EQ((size_t) peer_connection_number, dict_dump->size()); + + DictionaryValue::Iterator it(*dict_dump); + for (; !it.IsAtEnd(); it.Advance()) { + Value* value = NULL; + dict_dump->Get(it.key(), &value); + EXPECT_EQ(Value::TYPE_DICTIONARY, value->GetType()); + DictionaryValue* pc_dump = static_cast<DictionaryValue*>(value); + EXPECT_TRUE(pc_dump->HasKey("updateLog")); + EXPECT_TRUE(pc_dump->HasKey("stats")); + + // Verifies the number of updates. + pc_dump->Get("updateLog", &value); + EXPECT_EQ(Value::TYPE_LIST, value->GetType()); + ListValue* list = static_cast<ListValue*>(value); + EXPECT_EQ((size_t) update_number, list->GetSize()); + + // Verifies the number of stats tables. + pc_dump->Get("stats", &value); + EXPECT_EQ(Value::TYPE_DICTIONARY, value->GetType()); + DictionaryValue* dict = static_cast<DictionaryValue*>(value); + EXPECT_EQ((size_t) stats_number, dict->size()); + } + } + + // Verifies |dump| contains the correct statsTable and statsDataSeries for + // |pc|. + void VerifyStatsDump(Value* dump, + const PeerConnectionEntry& pc, + const string& report_type, + const string& report_id, + const StatsUnit& stats) { + EXPECT_NE((Value*)NULL, dump); + EXPECT_EQ(Value::TYPE_DICTIONARY, dump->GetType()); + + DictionaryValue* dict_dump = static_cast<DictionaryValue*>(dump); + Value* value = NULL; + dict_dump->Get(pc.getIdString(), &value); + DictionaryValue* pc_dump = static_cast<DictionaryValue*>(value); + + // Verifies there is one data series per stats name. + value = NULL; + pc_dump->Get("stats", &value); + EXPECT_EQ(Value::TYPE_DICTIONARY, value->GetType()); + + DictionaryValue* dataSeries = static_cast<DictionaryValue*>(value); + EXPECT_EQ(stats.values.size(), dataSeries->size()); + } }; IN_PROC_BROWSER_TEST_F(WebRTCInternalsBrowserTest, AddAndRemovePeerConnection) { @@ -504,10 +563,9 @@ IN_PROC_BROWSER_TEST_F(WebRTCInternalsBrowserTest, ConvertedGraphs) { ExecuteAndVerifyAddStats(pc, stats_type, stats_id, stats); // Verifies the graph data matches converted_values. - string graph_id_prefix = pc.getIdString() + "-" + stats_id; for (int i = 0; i < num_converted_stats; ++i) { - VerifyGraphDataPoint( - graph_id_prefix + "-" + converted_names[i], 1, converted_values[i]); + VerifyGraphDataPoint(pc.getIdString(), stats_id + "-" + converted_names[i], + 1, converted_values[i]); } } @@ -522,7 +580,8 @@ IN_PROC_BROWSER_TEST_F(WebRTCInternalsBrowserTest, ConvertedGraphs) { IN_PROC_BROWSER_TEST_F(WebRTCInternalsBrowserTest, MAYBE_WithRealPeerConnectionCall) { // Start a peerconnection call in the first window. - GURL url(test_server()->GetURL("files/media/peerconnection-call.html")); + ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); + GURL url(embedded_test_server()->GetURL("/media/peerconnection-call.html")); NavigateToURL(shell(), url); ASSERT_TRUE(ExecuteJavascript("call({video:true});")); ExpectTitle("OK"); @@ -601,4 +660,49 @@ IN_PROC_BROWSER_TEST_F(WebRTCInternalsBrowserTest, EXPECT_GT(count, 0); } +IN_PROC_BROWSER_TEST_F(WebRTCInternalsBrowserTest, CreatePageDump) { + GURL url("chrome://webrtc-internals"); + NavigateToURL(shell(), url); + + PeerConnectionEntry pc_0(1, 0); + pc_0.AddEvent("e1", "v1"); + pc_0.AddEvent("e2", "v2"); + PeerConnectionEntry pc_1(1, 1); + pc_1.AddEvent("e3", "v3"); + pc_1.AddEvent("e4", "v4"); + string pc_array = + "[" + pc_0.getAllUpdateString() + ", " + pc_1.getAllUpdateString() + "]"; + EXPECT_TRUE(ExecuteJavascript("updateAllPeerConnections(" + pc_array + ");")); + + // Verifies the peer connection data store can be created without stats. + string dump_json; + ASSERT_TRUE(ExecuteScriptAndExtractString( + shell()->web_contents(), + "window.domAutomationController.send(" + "JSON.stringify(peerConnectionDataStore));", + &dump_json)); + scoped_ptr<Value> dump; + dump.reset(base::JSONReader::Read(dump_json)); + VerifyPageDumpStructure(dump.get(), + 2 /*peer_connection_number*/, + 2 /*update_number*/, + 0 /*stats_number*/); + + // Adds a stats report. + const string type = "dummy"; + const string id = "1234"; + StatsUnit stats = { FAKE_TIME_STAMP }; + stats.values["bitrate"] = "2000"; + stats.values["framerate"] = "30"; + ExecuteAndVerifyAddStats(pc_0, type, id, stats); + + ASSERT_TRUE(ExecuteScriptAndExtractString( + shell()->web_contents(), + "window.domAutomationController.send(" + "JSON.stringify(peerConnectionDataStore));", + &dump_json)); + dump.reset(base::JSONReader::Read(dump_json)); + VerifyStatsDump(dump.get(), pc_0, type, id, stats); +} + } // namespace content diff --git a/content/browser/net/sqlite_persistent_cookie_store.cc b/content/browser/net/sqlite_persistent_cookie_store.cc index 7295c450a0..126a245d7f 100644 --- a/content/browser/net/sqlite_persistent_cookie_store.cc +++ b/content/browser/net/sqlite_persistent_cookie_store.cc @@ -18,6 +18,7 @@ #include "base/logging.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" +#include "base/metrics/field_trial.h" #include "base/metrics/histogram.h" #include "base/sequenced_task_runner.h" #include "base/string_util.h" @@ -596,7 +597,7 @@ bool SQLitePersistentCookieStore::Backend::InitializeDatabase() { UMA_HISTOGRAM_COUNTS("Cookie.DBSizeInKB", db_size / 1024 ); db_.reset(new sql::Connection); - db_->set_error_histogram_name("Sqlite.Cookie.Error"); + db_->set_histogram_tag("Cookie"); db_->set_error_delegate(new KillDatabaseErrorDelegate(this)); if (!db_->Open(path_)) { @@ -1219,7 +1220,15 @@ net::CookieStore* CreatePersistentCookieStore( BrowserThread::GetBlockingPool()->GetSequenceToken()), restore_old_session_cookies, storage_policy); - return new net::CookieMonster(persistent_store, cookie_monster_delegate); + net::CookieMonster* cookie_monster = + new net::CookieMonster(persistent_store, cookie_monster_delegate); + + const std::string cookie_priority_experiment_group = + base::FieldTrialList::FindFullName("CookieRetentionPriorityStudy"); + cookie_monster->SetPriorityAwareGarbageCollection( + cookie_priority_experiment_group == "ExperimentOn"); + + return cookie_monster; } } // namespace content diff --git a/content/browser/net/view_blob_internals_job_factory.cc b/content/browser/net/view_blob_internals_job_factory.cc index 1eab44b7fb..bd279c3639 100644 --- a/content/browser/net/view_blob_internals_job_factory.cc +++ b/content/browser/net/view_blob_internals_job_factory.cc @@ -7,7 +7,7 @@ #include "base/memory/scoped_ptr.h" #include "base/string_util.h" #include "content/public/common/url_constants.h" -#include "webkit/blob/view_blob_internals_job.h" +#include "webkit/browser/blob/view_blob_internals_job.h" namespace content { diff --git a/content/browser/plugin_browsertest.cc b/content/browser/plugin_browsertest.cc index 4e613a595b..9f93570c46 100644 --- a/content/browser/plugin_browsertest.cc +++ b/content/browser/plugin_browsertest.cc @@ -136,14 +136,14 @@ IN_PROC_BROWSER_TEST_F(PluginTest, UnloadNoCrash) { // Tests if a plugin executing a self deleting script using NPN_GetURL // works without crashing or hanging // Flaky: http://crbug.com/59327 -IN_PROC_BROWSER_TEST_F(PluginTest, SelfDeletePluginGetUrl) { +IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(SelfDeletePluginGetUrl)) { LoadAndWait(GetURL("self_delete_plugin_geturl.html")); } // Tests if a plugin executing a self deleting script using Invoke // works without crashing or hanging // Flaky. See http://crbug.com/30702 -IN_PROC_BROWSER_TEST_F(PluginTest, SelfDeletePluginInvoke) { +IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(SelfDeletePluginInvoke)) { LoadAndWait(GetURL("self_delete_plugin_invoke.html")); } @@ -166,7 +166,7 @@ IN_PROC_BROWSER_TEST_F(PluginTest, NPObjectSetException) { // This was never ported to Mac. The only thing remaining is to make // SimulateMouseClick get to Mac plugins, currently it doesn't work. IN_PROC_BROWSER_TEST_F(PluginTest, - SelfDeletePluginInvokeInSynchronousMouseUp) { + MAYBE(SelfDeletePluginInvokeInSynchronousMouseUp)) { NavigateToURL(shell(), GetURL("execute_script_delete_in_mouse_up.html")); string16 expected_title(ASCIIToUTF16("OK")); @@ -179,7 +179,7 @@ IN_PROC_BROWSER_TEST_F(PluginTest, #endif // Flaky, http://crbug.com/60071. -IN_PROC_BROWSER_TEST_F(PluginTest, GetURLRequest404Response) { +IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(GetURLRequest404Response)) { GURL url(URLRequestMockHTTPJob::GetMockUrl( base::FilePath().AppendASCII("npapi"). AppendASCII("plugin_url_request_404.html"))); @@ -189,7 +189,7 @@ IN_PROC_BROWSER_TEST_F(PluginTest, GetURLRequest404Response) { // Tests if a plugin executing a self deleting script using Invoke with // a modal dialog showing works without crashing or hanging // Disabled, flakily exceeds timeout, http://crbug.com/46257. -IN_PROC_BROWSER_TEST_F(PluginTest, SelfDeletePluginInvokeAlert) { +IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(SelfDeletePluginInvokeAlert)) { // Navigate asynchronously because if we waitd until it completes, there's a // race condition where the alert can come up before we start watching for it. shell()->LoadURL(GetURL("self_delete_plugin_invoke_alert.html")); @@ -204,7 +204,7 @@ IN_PROC_BROWSER_TEST_F(PluginTest, SelfDeletePluginInvokeAlert) { } // Test passing arguments to a plugin. -IN_PROC_BROWSER_TEST_F(PluginTest, Arguments) { +IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(Arguments)) { LoadAndWait(GetURL("arguments.html")); } diff --git a/content/browser/plugin_data_remover_impl.cc b/content/browser/plugin_data_remover_impl.cc index e1efc1f82b..de320b7d91 100644 --- a/content/browser/plugin_data_remover_impl.cc +++ b/content/browser/plugin_data_remover_impl.cc @@ -16,7 +16,7 @@ #include "content/browser/plugin_service_impl.h" #include "content/browser/renderer_host/pepper/pepper_flash_file_message_filter.h" #include "content/common/child_process_host_impl.h" -#include "content/common/plugin_messages.h" +#include "content/common/plugin_process_messages.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" #include "content/public/common/pepper_plugin_info.h" @@ -177,7 +177,7 @@ class PluginDataRemoverImpl::Context // IPC::Listener methods. virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { IPC_BEGIN_MESSAGE_MAP(Context, message) - IPC_MESSAGE_HANDLER(PluginHostMsg_ClearSiteDataResult, + IPC_MESSAGE_HANDLER(PluginProcessHostMsg_ClearSiteDataResult, OnClearSiteDataResult) IPC_MESSAGE_HANDLER(PpapiHostMsg_ClearSiteDataResult, OnPpapiClearSiteDataResult) @@ -243,7 +243,8 @@ class PluginDataRemoverImpl::Context if (is_ppapi) { msg = CreatePpapiClearSiteDataMsg(max_age); } else { - msg = new PluginMsg_ClearSiteData(std::string(), kClearAllData, max_age); + msg = new PluginProcessMsg_ClearSiteData( + std::string(), kClearAllData, max_age); } if (!channel_->Send(msg)) { NOTREACHED() << "Couldn't send ClearSiteData message"; @@ -253,13 +254,13 @@ class PluginDataRemoverImpl::Context } // Handles the PpapiHostMsg_ClearSiteDataResult message by delegating to the - // PluginHostMsg_ClearSiteDataResult handler. + // PluginProcessHostMsg_ClearSiteDataResult handler. void OnPpapiClearSiteDataResult(uint32 request_id, bool success) { DCHECK_EQ(0u, request_id); OnClearSiteDataResult(success); } - // Handles the PluginHostMsg_ClearSiteDataResult message. + // Handles the PluginProcessHostMsg_ClearSiteDataResult message. void OnClearSiteDataResult(bool success) { LOG_IF(ERROR, !success) << "ClearSiteData returned error"; UMA_HISTOGRAM_TIMES("ClearPluginData.time", diff --git a/content/browser/plugin_process_host.cc b/content/browser/plugin_process_host.cc index cce088fc6f..7b0c258cdf 100644 --- a/content/browser/plugin_process_host.cc +++ b/content/browser/plugin_process_host.cc @@ -25,7 +25,7 @@ #include "content/browser/gpu/gpu_data_manager_impl.h" #include "content/browser/plugin_service_impl.h" #include "content/common/child_process_host_impl.h" -#include "content/common/plugin_messages.h" +#include "content/common/plugin_process_messages.h" #include "content/common/resource_messages.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/content_browser_client.h" diff --git a/content/browser/plugin_process_host_mac.cc b/content/browser/plugin_process_host_mac.cc index 5c7916a8a7..f283ecd7b1 100644 --- a/content/browser/plugin_process_host_mac.cc +++ b/content/browser/plugin_process_host_mac.cc @@ -14,7 +14,6 @@ #include "base/process_util.h" #include "content/browser/browser_child_process_host_impl.h" #include "content/browser/plugin_process_host.h" -#include "content/common/plugin_messages.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/child_process_data.h" #include "ui/gfx/rect.h" diff --git a/content/browser/power_save_blocker_android.cc b/content/browser/power_save_blocker_android.cc index c349fe5f9e..23580497ae 100644 --- a/content/browser/power_save_blocker_android.cc +++ b/content/browser/power_save_blocker_android.cc @@ -5,24 +5,67 @@ #include "content/browser/power_save_blocker_impl.h" #include "base/logging.h" +#include "content/browser/android/content_video_view.h" +#include "content/public/browser/browser_thread.h" namespace content { class PowerSaveBlockerImpl::Delegate - : public base::RefCounted<PowerSaveBlockerImpl::Delegate> { + : public base::RefCountedThreadSafe<PowerSaveBlockerImpl::Delegate> { + public: + explicit Delegate(PowerSaveBlockerType type) : type_(type) {} + + // Does the actual work to apply or remove the desired power save block. + void ApplyBlock(); + void RemoveBlock(); + private: - friend class base::RefCounted<Delegate>; + friend class base::RefCountedThreadSafe<Delegate>; ~Delegate() {} + + // The counter of requests from clients for type + // kPowerSaveBlockPreventDisplaySleep. + static int blocker_count_; + const PowerSaveBlockerType type_; + + DISALLOW_COPY_AND_ASSIGN(Delegate); }; +int PowerSaveBlockerImpl::Delegate::blocker_count_ = 0; + +void PowerSaveBlockerImpl::Delegate::ApplyBlock() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + if (type_ != kPowerSaveBlockPreventDisplaySleep) + return; + + if (blocker_count_ == 0) + ContentVideoView::KeepScreenOn(true); + ++blocker_count_; +} + +void PowerSaveBlockerImpl::Delegate::RemoveBlock() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + if (type_ != kPowerSaveBlockPreventDisplaySleep) + return; + + --blocker_count_; + if (blocker_count_ == 0) + ContentVideoView::KeepScreenOn(false); +} + PowerSaveBlockerImpl::PowerSaveBlockerImpl(PowerSaveBlockerType type, - const std::string& reason) { - // TODO(wangxianzhu): Implement it. + const std::string& reason) + : delegate_(new Delegate(type)) { // This may be called on any thread. - NOTIMPLEMENTED(); + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::Bind(&Delegate::ApplyBlock, delegate_)); } PowerSaveBlockerImpl::~PowerSaveBlockerImpl() { + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::Bind(&Delegate::RemoveBlock, delegate_)); } } // namespace content diff --git a/content/browser/renderer_host/compositing_iosurface_mac.h b/content/browser/renderer_host/compositing_iosurface_mac.h index af2436f17e..2f1e11a2e0 100644 --- a/content/browser/renderer_host/compositing_iosurface_mac.h +++ b/content/browser/renderer_host/compositing_iosurface_mac.h @@ -59,7 +59,8 @@ class CompositingIOSurfaceMac { // Set IOSurface that will be drawn on the next NSView drawRect. void SetIOSurface(uint64 io_surface_handle, - const gfx::Size& size); + const gfx::Size& size, + float scale_factor); // Get the CGL renderer ID currently associated with this context. int GetRendererID(); @@ -84,7 +85,6 @@ class CompositingIOSurfaceMac { // |callback| is invoked when the operation is completed or failed. // Do no call this method again before |callback| is invoked. void CopyTo(const gfx::Rect& src_pixel_subrect, - float src_scale_factor, const gfx::Size& dst_pixel_size, const base::Callback<void(bool, const SkBitmap&)>& callback); @@ -92,7 +92,6 @@ class CompositingIOSurfaceMac { // VideoFrame, and invoke a callback to indicate success or failure. void CopyToVideoFrame( const gfx::Rect& src_subrect, - float src_scale_factor, const scoped_refptr<media::VideoFrame>& target, const base::Callback<void(bool)>& callback); @@ -113,9 +112,7 @@ class CompositingIOSurfaceMac { return pixel_io_surface_size_; } // In cocoa view units / DIPs. - const gfx::Size& io_surface_size() const { return io_surface_size_; } - - void SetDeviceScaleFactor(float scale_factor); + const gfx::Size& dip_io_surface_size() const { return dip_io_surface_size_; } bool is_vsync_disabled() const; @@ -265,7 +262,6 @@ class CompositingIOSurfaceMac { // operations. This allow certain optimizations. base::Closure CopyToVideoFrameWithinContext( const gfx::Rect& src_subrect, - float src_scale_factor, bool called_within_draw, const scoped_refptr<media::VideoFrame>& target, const base::Callback<void(bool)>& callback); @@ -275,7 +271,6 @@ class CompositingIOSurfaceMac { // |bitmap_output| or letter-boxed YV12 is written to |video_frame_output|. base::Closure CopyToSelectedOutputWithinContext( const gfx::Rect& src_pixel_subrect, - float src_scale_factor, const gfx::Rect& dst_pixel_rect, bool called_within_draw, const SkBitmap* bitmap_output, @@ -304,8 +299,7 @@ class CompositingIOSurfaceMac { void FailAllCopies(); void DestroyAllCopyContextsWithinContext(); - gfx::Rect IntersectWithIOSurface(const gfx::Rect& rect, - float scale_factor) const; + gfx::Rect IntersectWithIOSurface(const gfx::Rect& rect) const; // Cached pointer to IOSurfaceSupport Singleton. IOSurfaceSupport* io_surface_support_; @@ -320,7 +314,7 @@ class CompositingIOSurfaceMac { // The width and height of the io surface. gfx::Size pixel_io_surface_size_; // In pixels. - gfx::Size io_surface_size_; // In view units. + gfx::Size dip_io_surface_size_; // In view / density independent pixels. // The "live" OpenGL texture referring to this IOSurfaceRef. Note // that per the CGLTexImageIOSurface2D API we do not need to diff --git a/content/browser/renderer_host/compositing_iosurface_mac.mm b/content/browser/renderer_host/compositing_iosurface_mac.mm index 40bb0e4294..e58adcba74 100644 --- a/content/browser/renderer_host/compositing_iosurface_mac.mm +++ b/content/browser/renderer_host/compositing_iosurface_mac.mm @@ -335,13 +335,6 @@ void CompositingIOSurfaceMac::SwitchToContextOnNewWindow( context_ = new_context; } -void CompositingIOSurfaceMac::SetDeviceScaleFactor(float scale_factor) { - // TODO: After a resolution change, the DPI-ness of the view and the - // IOSurface might not be in sync. - io_surface_size_ = gfx::ToFlooredSize( - gfx::ScaleSize(pixel_io_surface_size_, 1.0 / scale_factor)); -} - bool CompositingIOSurfaceMac::is_vsync_disabled() const { return context_->is_vsync_disabled(); } @@ -366,8 +359,11 @@ CompositingIOSurfaceMac::~CompositingIOSurfaceMac() { } void CompositingIOSurfaceMac::SetIOSurface(uint64 io_surface_handle, - const gfx::Size& size) { + const gfx::Size& size, + float scale_factor) { pixel_io_surface_size_ = size; + dip_io_surface_size_ = gfx::ToFlooredSize( + gfx::ScaleSize(pixel_io_surface_size_, 1.0 / scale_factor)); CGLSetCurrentContext(context_->cgl_context()); MapIOSurfaceToTexture(io_surface_handle); CGLSetCurrentContext(0); @@ -407,17 +403,15 @@ void CompositingIOSurfaceMac::DrawIOSurface( gfx::ScaleSize(window_size, scale_factor)); glViewport(0, 0, pixel_window_size.width(), pixel_window_size.height()); - SetDeviceScaleFactor(scale_factor); - SurfaceQuad quad; - quad.set_size(io_surface_size_, pixel_io_surface_size_); + quad.set_size(dip_io_surface_size_, pixel_io_surface_size_); glMatrixMode(GL_PROJECTION); glLoadIdentity(); // Note that the projection keeps things in view units, so the use of - // window_size / io_surface_size_ (as opposed to the pixel_ variants) below is - // correct. + // window_size / dip_io_surface_size_ (as opposed to the pixel_ variants) + // below is correct. glOrtho(0, window_size.width(), window_size.height(), 0, -1, 1); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); @@ -435,20 +429,21 @@ void CompositingIOSurfaceMac::DrawIOSurface( glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); CHECK_GL_ERROR(); // Fill the resize gutters with white. - if (window_size.width() > io_surface_size_.width() || - window_size.height() > io_surface_size_.height()) { + if (window_size.width() > dip_io_surface_size_.width() || + window_size.height() > dip_io_surface_size_.height()) { context_->shader_program_cache()->UseSolidWhiteProgram(); SurfaceQuad filler_quad; - if (window_size.width() > io_surface_size_.width()) { + if (window_size.width() > dip_io_surface_size_.width()) { // Draw right-side gutter down to the bottom of the window. - filler_quad.set_rect(io_surface_size_.width(), 0.0f, + filler_quad.set_rect(dip_io_surface_size_.width(), 0.0f, window_size.width(), window_size.height()); DrawQuad(filler_quad); } - if (window_size.height() > io_surface_size_.height()) { + if (window_size.height() > dip_io_surface_size_.height()) { // Draw bottom gutter to the width of the IOSurface. - filler_quad.set_rect(0.0f, io_surface_size_.height(), - io_surface_size_.width(), window_size.height()); + filler_quad.set_rect( + 0.0f, dip_io_surface_size_.height(), + dip_io_surface_size_.width(), window_size.height()); DrawQuad(filler_quad); } } @@ -500,7 +495,7 @@ void CompositingIOSurfaceMac::DrawIOSurface( RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback callback; if (frame_subscriber->ShouldCaptureFrame(present_time, &frame, &callback)) { copy_done_callback = CopyToVideoFrameWithinContext( - gfx::Rect(pixel_io_surface_size_), scale_factor, true, frame, + gfx::Rect(pixel_io_surface_size_), true, frame, base::Bind(callback, present_time)); } } @@ -530,7 +525,6 @@ void CompositingIOSurfaceMac::DrawIOSurface( void CompositingIOSurfaceMac::CopyTo( const gfx::Rect& src_pixel_subrect, - float src_scale_factor, const gfx::Size& dst_pixel_size, const base::Callback<void(bool, const SkBitmap&)>& callback) { scoped_ptr<SkBitmap> output(new SkBitmap()); @@ -547,7 +541,7 @@ void CompositingIOSurfaceMac::CopyTo( CGLSetCurrentContext(context_->cgl_context()); const base::Closure copy_done_callback = CopyToSelectedOutputWithinContext( - src_pixel_subrect, src_scale_factor, gfx::Rect(dst_pixel_size), false, + src_pixel_subrect, gfx::Rect(dst_pixel_size), false, output.get(), NULL, base::Bind(&ReverseArgumentOrder, callback, base::Passed(&output))); CGLSetCurrentContext(0); @@ -557,12 +551,11 @@ void CompositingIOSurfaceMac::CopyTo( void CompositingIOSurfaceMac::CopyToVideoFrame( const gfx::Rect& src_pixel_subrect, - float src_scale_factor, const scoped_refptr<media::VideoFrame>& target, const base::Callback<void(bool)>& callback) { CGLSetCurrentContext(context_->cgl_context()); const base::Closure copy_done_callback = CopyToVideoFrameWithinContext( - src_pixel_subrect, src_scale_factor, false, target, callback); + src_pixel_subrect, false, target, callback); CGLSetCurrentContext(0); if (!copy_done_callback.is_null()) copy_done_callback.Run(); @@ -570,7 +563,6 @@ void CompositingIOSurfaceMac::CopyToVideoFrame( base::Closure CompositingIOSurfaceMac::CopyToVideoFrameWithinContext( const gfx::Rect& src_pixel_subrect, - float src_scale_factor, bool called_within_draw, const scoped_refptr<media::VideoFrame>& target, const base::Callback<void(bool)>& callback) { @@ -588,7 +580,7 @@ base::Closure CompositingIOSurfaceMac::CopyToVideoFrameWithinContext( DCHECK_LE(region_in_frame.bottom(), target->coded_size().height()); return CopyToSelectedOutputWithinContext( - src_pixel_subrect, src_scale_factor, region_in_frame, called_within_draw, + src_pixel_subrect, region_in_frame, called_within_draw, NULL, target, callback); } @@ -617,10 +609,6 @@ bool CompositingIOSurfaceMac::MapIOSurfaceToTexture( io_surface_support_->IOSurfaceGetWidth(io_surface_), io_surface_support_->IOSurfaceGetHeight(io_surface_)); - // TODO(thakis): Keep track of the view size over IPC. At the moment, - // the correct view units are computed on first paint. - io_surface_size_ = pixel_io_surface_size_; - GLenum target = GL_TEXTURE_RECTANGLE_ARB; glGenTextures(1, &texture_); glBindTexture(target, texture_); @@ -782,7 +770,6 @@ bool CompositingIOSurfaceMac::IsAsynchronousReadbackSupported() { base::Closure CompositingIOSurfaceMac::CopyToSelectedOutputWithinContext( const gfx::Rect& src_pixel_subrect, - float src_scale_factor, const gfx::Rect& dst_pixel_rect, bool called_within_draw, const SkBitmap* bitmap_output, @@ -819,8 +806,7 @@ base::Closure CompositingIOSurfaceMac::CopyToSelectedOutputWithinContext( return base::Bind(done_callback, false); // Send transform commands to the GPU. - const gfx::Rect src_rect = IntersectWithIOSurface(src_pixel_subrect, - src_scale_factor); + const gfx::Rect src_rect = IntersectWithIOSurface(src_pixel_subrect); copy_context->num_outputs = 0; if (bitmap_output) { if (copy_context->transformer->ResizeBilinear( @@ -1074,10 +1060,9 @@ void CompositingIOSurfaceMac::DestroyAllCopyContextsWithinContext() { } gfx::Rect CompositingIOSurfaceMac::IntersectWithIOSurface( - const gfx::Rect& rect, float scale_factor) const { + const gfx::Rect& rect) const { return gfx::IntersectRects(rect, - gfx::ToEnclosingRect(gfx::ScaleRect(gfx::Rect(io_surface_size_), - scale_factor))); + gfx::ToEnclosingRect(gfx::Rect(pixel_io_surface_size_))); } } // namespace content diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc index d06eb8b829..8839c21a1a 100644 --- a/content/browser/renderer_host/compositor_impl_android.cc +++ b/content/browser/renderer_host/compositor_impl_android.cc @@ -33,8 +33,8 @@ #include "third_party/khronos/GLES2/gl2.h" #include "third_party/khronos/GLES2/gl2ext.h" #include "ui/gfx/android/java_bitmap.h" +#include "webkit/common/gpu/webgraphicscontext3d_in_process_impl.h" #include "webkit/glue/webthread_impl.h" -#include "webkit/gpu/webgraphicscontext3d_in_process_impl.h" namespace gfx { class JavaBitmap; @@ -48,9 +48,11 @@ class DirectOutputSurface : public cc::OutputSurface { DirectOutputSurface(scoped_ptr<WebKit::WebGraphicsContext3D> context3d) : cc::OutputSurface(context3d.Pass()) {} - virtual void Reshape(gfx::Size size) OVERRIDE {} - virtual void PostSubBuffer(gfx::Rect rect, const cc::LatencyInfo&) OVERRIDE {} - virtual void SwapBuffers(const cc::LatencyInfo&) OVERRIDE {} + virtual void Reshape(gfx::Size size, float scale_factor) OVERRIDE {} + virtual void PostSubBuffer(gfx::Rect rect, const ui::LatencyInfo&) OVERRIDE {} + virtual void SwapBuffers(const ui::LatencyInfo&) OVERRIDE { + context3d()->shallowFlushCHROMIUM(); + } }; static bool g_initialized = false; @@ -199,6 +201,7 @@ void CompositorImpl::SetVisible(bool visible) { host_.reset(); } else if (!host_) { cc::LayerTreeSettings settings; + settings.compositor_name = "BrowserCompositor"; settings.refresh_rate = 60.0; settings.impl_side_painting = false; settings.calculate_top_controls_position = false; @@ -370,10 +373,6 @@ scoped_ptr<cc::OutputSurface> CompositorImpl::CreateOutputSurface() { } } -scoped_ptr<cc::InputHandlerClient> CompositorImpl::CreateInputHandlerClient() { - return scoped_ptr<cc::InputHandlerClient>(); -} - void CompositorImpl::DidCompleteSwapBuffers() { client_->OnSwapBuffersCompleted(); } diff --git a/content/browser/renderer_host/compositor_impl_android.h b/content/browser/renderer_host/compositor_impl_android.h index e1277532a9..eafafc3374 100644 --- a/content/browser/renderer_host/compositor_impl_android.h +++ b/content/browser/renderer_host/compositor_impl_android.h @@ -75,8 +75,6 @@ class CONTENT_EXPORT CompositorImpl virtual void ApplyScrollAndScale(gfx::Vector2d scroll_delta, float page_scale) OVERRIDE {} virtual scoped_ptr<cc::OutputSurface> CreateOutputSurface() OVERRIDE; - virtual scoped_ptr<cc::InputHandlerClient> CreateInputHandlerClient() - OVERRIDE; virtual void DidInitializeOutputSurface(bool success) OVERRIDE {} virtual void WillCommit() OVERRIDE {} virtual void DidCommit() OVERRIDE {} diff --git a/content/browser/renderer_host/database_message_filter.cc b/content/browser/renderer_host/database_message_filter.cc index 8e5f51d677..d4e79b3a71 100644 --- a/content/browser/renderer_host/database_message_filter.cc +++ b/content/browser/renderer_host/database_message_filter.cc @@ -17,8 +17,8 @@ #include "googleurl/src/gurl.h" #include "third_party/sqlite/sqlite3.h" #include "webkit/base/origin_url_conversions.h" -#include "webkit/database/database_util.h" -#include "webkit/database/vfs_backend.h" +#include "webkit/browser/database/database_util.h" +#include "webkit/browser/database/vfs_backend.h" #include "webkit/quota/quota_manager.h" #if defined(OS_POSIX) diff --git a/content/browser/renderer_host/database_message_filter.h b/content/browser/renderer_host/database_message_filter.h index 26d9be30c7..23aa985d0d 100644 --- a/content/browser/renderer_host/database_message_filter.h +++ b/content/browser/renderer_host/database_message_filter.h @@ -8,8 +8,8 @@ #include "base/hash_tables.h" #include "base/string16.h" #include "content/public/browser/browser_message_filter.h" -#include "webkit/database/database_connections.h" -#include "webkit/database/database_tracker.h" +#include "webkit/browser/database/database_tracker.h" +#include "webkit/common/database/database_connections.h" #include "webkit/quota/quota_types.h" namespace content { diff --git a/content/browser/renderer_host/dip_util.cc b/content/browser/renderer_host/dip_util.cc index 575232c659..8ef2d6c466 100644 --- a/content/browser/renderer_host/dip_util.cc +++ b/content/browser/renderer_host/dip_util.cc @@ -27,40 +27,40 @@ ui::ScaleFactor GetScaleFactorForView(const RenderWidgetHostView* view) { return ui::GetScaleFactorForNativeView(view ? view->GetNativeView() : NULL); } -gfx::Point ConvertPointToDIP(const RenderWidgetHostView* view, - const gfx::Point& point_in_pixel) { +gfx::Point ConvertViewPointToDIP(const RenderWidgetHostView* view, + const gfx::Point& point_in_pixel) { return gfx::ToFlooredPoint( gfx::ScalePoint(point_in_pixel, 1.0f / GetScaleForView(view))); } -gfx::Size ConvertSizeToDIP(const RenderWidgetHostView* view, - const gfx::Size& size_in_pixel) { +gfx::Size ConvertViewSizeToPixel(const RenderWidgetHostView* view, + const gfx::Size& size_in_dip) { return gfx::ToFlooredSize( - gfx::ScaleSize(size_in_pixel, 1.0f / GetScaleForView(view))); + gfx::ScaleSize(size_in_dip, GetScaleForView(view))); } -gfx::Rect ConvertRectToDIP(const RenderWidgetHostView* view, - const gfx::Rect& rect_in_pixel) { - float scale = 1.0f / GetScaleForView(view); - return gfx::ToFlooredRectDeprecated(gfx::ScaleRect(rect_in_pixel, scale)); +gfx::Rect ConvertViewRectToPixel(const RenderWidgetHostView* view, + const gfx::Rect& rect_in_dip) { + return ConvertRectToPixel(GetScaleForView(view), rect_in_dip); } -gfx::Point ConvertPointToPixel(const RenderWidgetHostView* view, - const gfx::Point& point_in_dip) { - return gfx::ToFlooredPoint( - gfx::ScalePoint(point_in_dip, GetScaleForView(view))); +gfx::Size ConvertSizeToDIP(float scale_factor, + const gfx::Size& size_in_pixel) { + return gfx::ToFlooredSize( + gfx::ScaleSize(size_in_pixel, 1.0f / scale_factor)); } -gfx::Size ConvertSizeToPixel(const RenderWidgetHostView* view, - const gfx::Size& size_in_dip) { - return gfx::ToFlooredSize( - gfx::ScaleSize(size_in_dip, GetScaleForView(view))); +gfx::Rect ConvertRectToDIP(float scale_factor, + const gfx::Rect& rect_in_pixel) { + return gfx::ToFlooredRectDeprecated( + gfx::ScaleRect(rect_in_pixel, 1.0f / scale_factor)); } -gfx::Rect ConvertRectToPixel(const RenderWidgetHostView* view, + +gfx::Rect ConvertRectToPixel(float scale_factor, const gfx::Rect& rect_in_dip) { - float scale = GetScaleForView(view); - return gfx::ToFlooredRectDeprecated(gfx::ScaleRect(rect_in_dip, scale)); + return gfx::ToFlooredRectDeprecated( + gfx::ScaleRect(rect_in_dip, scale_factor)); } } // namespace content diff --git a/content/browser/renderer_host/dip_util.h b/content/browser/renderer_host/dip_util.h index aea4c34b52..a7e1876ec7 100644 --- a/content/browser/renderer_host/dip_util.h +++ b/content/browser/renderer_host/dip_util.h @@ -24,18 +24,20 @@ CONTENT_EXPORT ui::ScaleFactor GetScaleFactorForView( // Utility functions that convert point/size/rect between DIP and pixel // coordinate system. -CONTENT_EXPORT gfx::Point ConvertPointToDIP(const RenderWidgetHostView* view, - const gfx::Point& point_in_pixel); -CONTENT_EXPORT gfx::Size ConvertSizeToDIP(const RenderWidgetHostView* view, - const gfx::Size& size_in_pixel); -CONTENT_EXPORT gfx::Rect ConvertRectToDIP(const RenderWidgetHostView* view, - const gfx::Rect& rect_in_pixel); -CONTENT_EXPORT gfx::Point ConvertPointToPixel(const RenderWidgetHostView* view, - const gfx::Point& point_in_dip); -CONTENT_EXPORT gfx::Size ConvertSizeToPixel(const RenderWidgetHostView* view, - const gfx::Size& size_in_dip); -CONTENT_EXPORT gfx::Rect ConvertRectToPixel(const RenderWidgetHostView* view, - const gfx::Rect& rect_in_dip); +CONTENT_EXPORT gfx::Point ConvertViewPointToDIP( + const RenderWidgetHostView* view, const gfx::Point& point_in_pixel); +CONTENT_EXPORT gfx::Size ConvertViewSizeToPixel( + const RenderWidgetHostView* view, const gfx::Size& size_in_dip); +CONTENT_EXPORT gfx::Rect ConvertViewRectToPixel( + const RenderWidgetHostView* view, const gfx::Rect& rect_in_dip); + +CONTENT_EXPORT gfx::Size ConvertSizeToDIP( + float scale_factor, const gfx::Size& size_in_pixel); +CONTENT_EXPORT gfx::Rect ConvertRectToDIP( + float scale_factor, const gfx::Rect& rect_in_pixel); +CONTENT_EXPORT gfx::Rect ConvertRectToPixel( + float scale_factor, const gfx::Rect& rect_in_dip); + } // namespace content #endif // CONTENT_BROWSER_RENDERER_HOST_DIP_UTIL_H_ diff --git a/content/browser/renderer_host/event_with_latency_info.h b/content/browser/renderer_host/event_with_latency_info.h index f7891fff13..e481afa653 100644 --- a/content/browser/renderer_host/event_with_latency_info.h +++ b/content/browser/renderer_host/event_with_latency_info.h @@ -5,7 +5,7 @@ #ifndef CONTENT_BROWSER_RENDERER_HOST_EVENT_WITH_LATENCY_INFO_H_ #define CONTENT_BROWSER_RENDERER_HOST_EVENT_WITH_LATENCY_INFO_H_ -#include <cc/debug/latency_info.h> +#include "ui/base/latency_info.h" namespace WebKit { class WebGestureEvent; @@ -19,9 +19,9 @@ template <typename T> class EventWithLatencyInfo { public: T event; - cc::LatencyInfo latency; + ui::LatencyInfo latency; - EventWithLatencyInfo(const T& e, const cc::LatencyInfo& l) + EventWithLatencyInfo(const T& e, const ui::LatencyInfo& l) : event(e), latency(l) {} EventWithLatencyInfo() {} diff --git a/content/browser/renderer_host/gpu_message_filter.cc b/content/browser/renderer_host/gpu_message_filter.cc index fb6430aad5..c396a7f9fc 100644 --- a/content/browser/renderer_host/gpu_message_filter.cc +++ b/content/browser/renderer_host/gpu_message_filter.cc @@ -18,6 +18,7 @@ #include "content/common/gpu/gpu_messages.h" #include "content/port/browser/render_widget_host_view_frame_subscriber.h" #include "content/public/common/content_switches.h" +#include "gpu/command_buffer/service/gpu_switches.h" namespace content { @@ -65,9 +66,12 @@ GpuMessageFilter::GpuMessageFilter(int render_process_id, // contexts with the compositor context. share_contexts_ = true; #else - // Share contexts when compositing webview plugin. + // Share contexts when compositing webview plugin or using share groups + // for asynchronous texture uploads. if (!CommandLine::ForCurrentProcess()->HasSwitch( - switches::kDisableBrowserPluginCompositing)) + switches::kDisableBrowserPluginCompositing) || + CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableShareGroupAsyncTextureUpload)) share_contexts_ = true; #endif } @@ -221,7 +225,7 @@ void GpuMessageFilter::OnCreateViewCommandBuffer( void GpuMessageFilter::EstablishChannelCallback( IPC::Message* reply, const IPC::ChannelHandle& channel, - const GPUInfo& gpu_info) { + const gpu::GPUInfo& gpu_info) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); GpuHostMsg_EstablishGpuChannel::WriteReplyParams( diff --git a/content/browser/renderer_host/gpu_message_filter.h b/content/browser/renderer_host/gpu_message_filter.h index 20c0b12e05..bd9c10fefa 100644 --- a/content/browser/renderer_host/gpu_message_filter.h +++ b/content/browser/renderer_host/gpu_message_filter.h @@ -18,10 +18,13 @@ class GpuProcessHost; struct GPUCreateCommandBufferConfig; +namespace gpu { +struct GPUInfo; +} + namespace content { class RenderWidgetHelper; class RenderWidgetHostViewFrameSubscriber; -struct GPUInfo; // A message filter for messages from the renderer to the GpuProcessHost(UIShim) // in the browser. Such messages are typically destined for the GPU process, @@ -64,7 +67,7 @@ class GpuMessageFilter : public BrowserMessageFilter { // Helper callbacks for the message handlers. void EstablishChannelCallback(IPC::Message* reply, const IPC::ChannelHandle& channel, - const GPUInfo& gpu_info); + const gpu::GPUInfo& gpu_info); void CreateCommandBufferCallback(IPC::Message* reply, int32 route_id); void BeginAllFrameSubscriptions(); diff --git a/content/browser/renderer_host/image_transport_factory_android.cc b/content/browser/renderer_host/image_transport_factory_android.cc index bfb6dbb1b0..212b69f7eb 100644 --- a/content/browser/renderer_host/image_transport_factory_android.cc +++ b/content/browser/renderer_host/image_transport_factory_android.cc @@ -7,12 +7,12 @@ #include "base/memory/singleton.h" #include "content/browser/gpu/browser_gpu_channel_host_factory.h" #include "content/browser/renderer_host/compositor_impl_android.h" -#include "content/common/gpu/gpu_process_launch_causes.h" #include "content/common/gpu/client/gl_helper.h" #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h" +#include "content/common/gpu/gpu_process_launch_causes.h" #include "third_party/WebKit/Source/Platform/chromium/public/WebGraphicsContext3D.h" #include "third_party/khronos/GLES2/gl2.h" -#include "webkit/gpu/webgraphicscontext3d_in_process_impl.h" +#include "webkit/common/gpu/webgraphicscontext3d_in_process_impl.h" namespace content { diff --git a/content/browser/renderer_host/java/DEPS b/content/browser/renderer_host/java/DEPS new file mode 100644 index 0000000000..6866a1565e --- /dev/null +++ b/content/browser/renderer_host/java/DEPS @@ -0,0 +1,3 @@ +include_rules = [ + "+content/common_child", # For java bridge bindings +] diff --git a/content/browser/renderer_host/java/java_bridge_channel_host.h b/content/browser/renderer_host/java/java_bridge_channel_host.h index 4c58f8d166..2e8968bcda 100644 --- a/content/browser/renderer_host/java/java_bridge_channel_host.h +++ b/content/browser/renderer_host/java/java_bridge_channel_host.h @@ -5,7 +5,7 @@ #ifndef CONTENT_BROWSER_RENDERER_HOST_JAVA_JAVA_BRIDGE_CHANNEL_HOST_H_ #define CONTENT_BROWSER_RENDERER_HOST_JAVA_JAVA_BRIDGE_CHANNEL_HOST_H_ -#include "content/common/np_channel_base.h" +#include "content/common_child/np_channel_base.h" namespace content { diff --git a/content/browser/renderer_host/java/java_bridge_dispatcher_host.cc b/content/browser/renderer_host/java/java_bridge_dispatcher_host.cc index e3d2cd2df0..a1f1624cfe 100644 --- a/content/browser/renderer_host/java/java_bridge_dispatcher_host.cc +++ b/content/browser/renderer_host/java/java_bridge_dispatcher_host.cc @@ -11,8 +11,8 @@ #include "content/browser/renderer_host/render_view_host_impl.h" #include "content/common/child_process.h" #include "content/common/java_bridge_messages.h" -#include "content/common/npobject_stub.h" -#include "content/common/npobject_util.h" // For CreateNPVariantParam() +#include "content/common_child/npobject_stub.h" +#include "content/common_child/npobject_util.h" // For CreateNPVariantParam() #include "content/public/browser/browser_thread.h" #include "content/public/browser/render_process_host.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebBindings.h" diff --git a/content/browser/renderer_host/java/java_bridge_dispatcher_host.h b/content/browser/renderer_host/java/java_bridge_dispatcher_host.h index a0bc341c95..2f0c5f6a5b 100644 --- a/content/browser/renderer_host/java/java_bridge_dispatcher_host.h +++ b/content/browser/renderer_host/java/java_bridge_dispatcher_host.h @@ -9,7 +9,7 @@ #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "base/string16.h" -#include "content/common/npobject_stub.h" +#include "content/common_child/npobject_stub.h" #include "content/public/browser/render_view_host_observer.h" class RouteIDGenerator; diff --git a/content/browser/renderer_host/media/video_capture_manager.cc b/content/browser/renderer_host/media/video_capture_manager.cc index 5605abbecb..d722514d53 100644 --- a/content/browser/renderer_host/media/video_capture_manager.cc +++ b/content/browser/renderer_host/media/video_capture_manager.cc @@ -18,9 +18,13 @@ #include "content/public/common/content_switches.h" #include "content/public/common/media_stream_request.h" #include "media/video/capture/fake_video_capture_device.h" -#include "media/video/capture/screen/screen_capture_device.h" #include "media/video/capture/video_capture_device.h" +#if (defined(OS_LINUX) && defined(USE_X11)) || \ + defined(OS_MACOSX) || defined(OS_WIN) +#include "media/video/capture/screen/screen_capture_device.h" +#endif + namespace content { // Starting id for the first capture session. diff --git a/content/browser/renderer_host/media/webrtc_logging_handler_host.cc b/content/browser/renderer_host/media/webrtc_logging_handler_host.cc index 00d90fd855..10e2101c80 100644 --- a/content/browser/renderer_host/media/webrtc_logging_handler_host.cc +++ b/content/browser/renderer_host/media/webrtc_logging_handler_host.cc @@ -10,7 +10,11 @@ namespace content { +#if defined(OS_ANDROID) +const size_t kWebRtcLogSize = 1 * 1024 * 1024; // 1 MB +#else const size_t kWebRtcLogSize = 6 * 1024 * 1024; // 6 MB +#endif WebRtcLoggingHandlerHost::WebRtcLoggingHandlerHost() { } @@ -38,7 +42,8 @@ bool WebRtcLoggingHandlerHost::OnMessageReceived(const IPC::Message& message, return handled; } -void WebRtcLoggingHandlerHost::OnOpenLog() { +void WebRtcLoggingHandlerHost::OnOpenLog(const std::string& app_session_id, + const std::string& app_url) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); DCHECK(!base::SharedMemory::IsHandleValid(shared_memory_.handle())); @@ -55,6 +60,8 @@ void WebRtcLoggingHandlerHost::OnOpenLog() { return; } + app_session_id_ = app_session_id; + app_url_ = app_url; Send(new WebRtcLoggingMsg_LogOpened(foreign_memory_handle, kWebRtcLogSize)); } diff --git a/content/browser/renderer_host/media/webrtc_logging_handler_host.h b/content/browser/renderer_host/media/webrtc_logging_handler_host.h index f3ab4a495a..7ab7fbaa93 100644 --- a/content/browser/renderer_host/media/webrtc_logging_handler_host.h +++ b/content/browser/renderer_host/media/webrtc_logging_handler_host.h @@ -30,9 +30,11 @@ class WebRtcLoggingHandlerHost : public BrowserMessageFilter { virtual ~WebRtcLoggingHandlerHost(); - void OnOpenLog(); + void OnOpenLog(const std::string& app_session_id, const std::string& app_url); base::SharedMemory shared_memory_; + std::string app_session_id_; + std::string app_url_; DISALLOW_COPY_AND_ASSIGN(WebRtcLoggingHandlerHost); }; diff --git a/content/browser/renderer_host/memory_benchmark_message_filter.cc b/content/browser/renderer_host/memory_benchmark_message_filter.cc new file mode 100644 index 0000000000..d559852894 --- /dev/null +++ b/content/browser/renderer_host/memory_benchmark_message_filter.cc @@ -0,0 +1,42 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/renderer_host/memory_benchmark_message_filter.h" + +#include "content/common/memory_benchmark_messages.h" + +#if defined(USE_TCMALLOC) && (defined(OS_LINUX) || defined(OS_ANDROID)) + +#include "third_party/tcmalloc/chromium/src/gperftools/heap-profiler.h" + +namespace content { + +MemoryBenchmarkMessageFilter::MemoryBenchmarkMessageFilter() { +} + +bool MemoryBenchmarkMessageFilter::OnMessageReceived( + const IPC::Message& message, + bool* message_was_ok) { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP_EX(MemoryBenchmarkMessageFilter, + message, + *message_was_ok) + IPC_MESSAGE_HANDLER(MemoryBenchmarkHostMsg_HeapProfilerDump, + OnHeapProfilerDump) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + return handled; +} + +MemoryBenchmarkMessageFilter::~MemoryBenchmarkMessageFilter() { +} + +void MemoryBenchmarkMessageFilter::OnHeapProfilerDump( + const std::string& reason) { + ::HeapProfilerDump(reason.c_str()); +} + +} // namespace content + +#endif // defined(USE_TCMALLOC) && (defined(OS_LINUX) || defined(OS_ANDROID)) diff --git a/content/browser/renderer_host/memory_benchmark_message_filter.h b/content/browser/renderer_host/memory_benchmark_message_filter.h new file mode 100644 index 0000000000..da5a6aa4b5 --- /dev/null +++ b/content/browser/renderer_host/memory_benchmark_message_filter.h @@ -0,0 +1,30 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_RENDERER_HOST_MEMORY_BENCHMARK_MESSAGE_FILTER_H_ +#define CONTENT_BROWSER_RENDERER_HOST_MEMORY_BENCHMARK_MESSAGE_FILTER_H_ + +#include <string> + +#include "content/public/browser/browser_message_filter.h" + +namespace content { + +class MemoryBenchmarkMessageFilter : public BrowserMessageFilter { + public: + MemoryBenchmarkMessageFilter(); + + virtual bool OnMessageReceived(const IPC::Message& message, + bool* message_was_ok) OVERRIDE; + private: + virtual ~MemoryBenchmarkMessageFilter(); + + void OnHeapProfilerDump(const std::string& reason); + + DISALLOW_COPY_AND_ASSIGN(MemoryBenchmarkMessageFilter); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_RENDERER_HOST_MEMORY_BENCHMARK_MESSAGE_FILTER_H_ diff --git a/content/browser/renderer_host/overscroll_controller.cc b/content/browser/renderer_host/overscroll_controller.cc index 14a82e6fe9..66c23cc505 100644 --- a/content/browser/renderer_host/overscroll_controller.cc +++ b/content/browser/renderer_host/overscroll_controller.cc @@ -16,6 +16,7 @@ OverscrollController::OverscrollController( RenderWidgetHostImpl* render_widget_host) : render_widget_host_(render_widget_host), overscroll_mode_(OVERSCROLL_NONE), + scroll_state_(STATE_UNKNOWN), overscroll_delta_x_(0.f), overscroll_delta_y_(0.f), delegate_(NULL) { @@ -26,7 +27,26 @@ OverscrollController::~OverscrollController() { bool OverscrollController::WillDispatchEvent( const WebKit::WebInputEvent& event, - const cc::LatencyInfo& latency_info) { + const ui::LatencyInfo& latency_info) { + if (scroll_state_ != STATE_UNKNOWN) { + if (event.type == WebKit::WebInputEvent::GestureScrollEnd) { + scroll_state_ = STATE_UNKNOWN; + } else if (event.type == WebKit::WebInputEvent::GestureFlingStart) { + // Start of a fling indicates the end of a scroll, both from touchpad and + // touchscreen. So it is not necessary to check |sourceDevice| of the + // event. + scroll_state_ = STATE_UNKNOWN; + } else if (event.type == WebKit::WebInputEvent::MouseWheel) { + const WebKit::WebMouseWheelEvent& wheel = + static_cast<const WebKit::WebMouseWheelEvent&>(event); + if (wheel.hasPreciseScrollingDeltas && + (wheel.phase == WebKit::WebMouseWheelEvent::PhaseEnded || + wheel.phase == WebKit::WebMouseWheelEvent::PhaseCancelled)) { + scroll_state_ = STATE_UNKNOWN; + } + } + } + if (DispatchEventCompletesAction(event)) { CompleteAction(); @@ -79,14 +99,24 @@ bool OverscrollController::WillDispatchEvent( void OverscrollController::ReceivedEventACK(const WebKit::WebInputEvent& event, bool processed) { - if (processed) + if (processed) { + // If a scroll event is consumed by the page, i.e. some content on the page + // has been scrolled, then there is not going to be an overscroll gesture, + // until the current scroll ends, and a new scroll gesture starts. + if (scroll_state_ == STATE_UNKNOWN && + (event.type == WebKit::WebInputEvent::MouseWheel || + event.type == WebKit::WebInputEvent::GestureScrollUpdate)) { + scroll_state_ = STATE_CONTENT_SCROLLING; + } return; + } ProcessEventForOverscroll(event); } void OverscrollController::Reset() { overscroll_mode_ = OVERSCROLL_NONE; overscroll_delta_x_ = overscroll_delta_y_ = 0.f; + scroll_state_ = STATE_UNKNOWN; } bool OverscrollController::DispatchEventCompletesAction ( @@ -177,10 +207,11 @@ void OverscrollController::ProcessEventForOverscroll( case WebKit::WebInputEvent::MouseWheel: { const WebKit::WebMouseWheelEvent& wheel = static_cast<const WebKit::WebMouseWheelEvent&>(event); - if (wheel.hasPreciseScrollingDeltas) { - ProcessOverscroll(wheel.deltaX * wheel.accelerationRatioX, - wheel.deltaY * wheel.accelerationRatioY); - } + if (!wheel.hasPreciseScrollingDeltas) + return; + + ProcessOverscroll(wheel.deltaX * wheel.accelerationRatioX, + wheel.deltaY * wheel.accelerationRatioY); break; } case WebKit::WebInputEvent::GestureScrollUpdate: { @@ -223,6 +254,8 @@ void OverscrollController::ProcessEventForOverscroll( } void OverscrollController::ProcessOverscroll(float delta_x, float delta_y) { + if (scroll_state_ == STATE_CONTENT_SCROLLING) + return; overscroll_delta_x_ += delta_x; overscroll_delta_y_ += delta_y; @@ -292,6 +325,8 @@ void OverscrollController::SetOverscrollMode(OverscrollMode mode) { overscroll_mode_ = mode; if (overscroll_mode_ == OVERSCROLL_NONE) overscroll_delta_x_ = overscroll_delta_y_ = 0.f; + else + scroll_state_ = STATE_OVERSCROLLING; if (delegate_) delegate_->OnOverscrollModeChange(old_mode, overscroll_mode_); } diff --git a/content/browser/renderer_host/overscroll_controller.h b/content/browser/renderer_host/overscroll_controller.h index 6f82d0af38..39d15dcc85 100644 --- a/content/browser/renderer_host/overscroll_controller.h +++ b/content/browser/renderer_host/overscroll_controller.h @@ -9,7 +9,7 @@ #include "base/compiler_specific.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" -namespace cc { +namespace ui { struct LatencyInfo; } @@ -44,7 +44,7 @@ class OverscrollController { // updated properly. // Returns true if the event should be dispatched, false otherwise. bool WillDispatchEvent(const WebKit::WebInputEvent& event, - const cc::LatencyInfo& latency_info); + const ui::LatencyInfo& latency_info); // This must be called when the ACK for any event comes in. This updates the // overscroll gesture status as appropriate. @@ -62,6 +62,14 @@ class OverscrollController { private: friend class MockRenderWidgetHost; + // Different scrolling states. + enum ScrollState { + STATE_UNKNOWN, + STATE_PENDING, + STATE_CONTENT_SCROLLING, + STATE_OVERSCROLLING, + }; + // Returns true if the event indicates that the in-progress overscroll gesture // can now be completed. bool DispatchEventCompletesAction( @@ -96,6 +104,13 @@ class OverscrollController { // The current state of overscroll gesture. OverscrollMode overscroll_mode_; + // Used to keep track of the scrolling state. + // If scrolling starts, and some scroll events are consumed at the beginning + // of the scroll (i.e. some content on the web-page was scrolled), then do not + // process any of the subsequent scroll events for generating overscroll + // gestures. + ScrollState scroll_state_; + // The amount of overscroll in progress. These values are invalid when // |overscroll_mode_| is set to OVERSCROLL_NONE. float overscroll_delta_x_; diff --git a/content/browser/renderer_host/p2p/socket_dispatcher_host.cc b/content/browser/renderer_host/p2p/socket_dispatcher_host.cc index 36b921067f..25fbea5cfb 100644 --- a/content/browser/renderer_host/p2p/socket_dispatcher_host.cc +++ b/content/browser/renderer_host/p2p/socket_dispatcher_host.cc @@ -69,14 +69,7 @@ class P2PSocketDispatcherHost::DnsRequest { return; } - // TODO(szym): Redundant check. http://crbug.com/126211 - if (addresses_.empty()) { - LOG(ERROR) << "Received 0 addresses when trying to resolve address for " - << host_name_; - done_callback_.Run(net::IPAddressNumber()); - return; - } - + DCHECK(!addresses_.empty()); done_callback_.Run(addresses_.front().address()); } diff --git a/content/browser/renderer_host/pepper/pepper_message_filter.cc b/content/browser/renderer_host/pepper/pepper_message_filter.cc index 03a6534628..328c4ec4be 100644 --- a/content/browser/renderer_host/pepper/pepper_message_filter.cc +++ b/content/browser/renderer_host/pepper/pepper_message_filter.cc @@ -365,20 +365,24 @@ void PepperMessageFilter::DoTCPServerListen(bool allowed, int32_t backlog) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); if (!allowed) { - Send(new PpapiMsg_PPBTCPServerSocket_ListenACK(routing_id, - plugin_dispatcher_id, - socket_resource, - 0, - PP_ERROR_FAILED)); + Send(new PpapiMsg_PPBTCPServerSocket_ListenACK( + routing_id, + plugin_dispatcher_id, + socket_resource, + 0, + NetAddressPrivateImpl::kInvalidNetAddress, + PP_ERROR_FAILED)); return; } uint32 socket_id = GenerateSocketID(); if (socket_id == kInvalidSocketID) { - Send(new PpapiMsg_PPBTCPServerSocket_ListenACK(routing_id, - plugin_dispatcher_id, - socket_resource, - 0, - PP_ERROR_NOSPACE)); + Send(new PpapiMsg_PPBTCPServerSocket_ListenACK( + routing_id, + plugin_dispatcher_id, + socket_resource, + 0, + NetAddressPrivateImpl::kInvalidNetAddress, + PP_ERROR_NOSPACE)); return; } PepperTCPServerSocket* socket = new PepperTCPServerSocket( diff --git a/content/browser/renderer_host/pepper/pepper_tcp_server_socket.cc b/content/browser/renderer_host/pepper/pepper_tcp_server_socket.cc index bc65f6ef53..f0ffb275e1 100644 --- a/content/browser/renderer_host/pepper/pepper_tcp_server_socket.cc +++ b/content/browser/renderer_host/pepper/pepper_tcp_server_socket.cc @@ -84,6 +84,7 @@ void PepperTCPServerSocket::CancelListenRequest() { plugin_dispatcher_id_, socket_resource_, 0, + NetAddressPrivateImpl::kInvalidNetAddress, PP_ERROR_FAILED)); BrowserThread::PostTask( BrowserThread::IO, @@ -107,15 +108,27 @@ void PepperTCPServerSocket::OnListenCompleted(int result) { if (result != net::OK) { CancelListenRequest(); - } else { - manager_->Send(new PpapiMsg_PPBTCPServerSocket_ListenACK( - routing_id_, - plugin_dispatcher_id_, - socket_resource_, - socket_id_, - PP_OK)); - state_ = LISTENING; + return; + } + + net::IPEndPoint end_point; + PP_NetAddress_Private addr; + if (socket_->GetLocalAddress(&end_point) != net::OK || + !NetAddressPrivateImpl::IPEndPointToNetAddress(end_point.address(), + end_point.port(), + &addr)) { + CancelListenRequest(); + return; } + + manager_->Send(new PpapiMsg_PPBTCPServerSocket_ListenACK( + routing_id_, + plugin_dispatcher_id_, + socket_resource_, + socket_id_, + addr, + PP_OK)); + state_ = LISTENING; } void PepperTCPServerSocket::OnAcceptCompleted( diff --git a/content/browser/renderer_host/render_message_filter.cc b/content/browser/renderer_host/render_message_filter.cc index 3b4031b93f..f7059a90d9 100644 --- a/content/browser/renderer_host/render_message_filter.cc +++ b/content/browser/renderer_host/render_message_filter.cc @@ -400,7 +400,7 @@ bool RenderMessageFilter::OnMessageReceived(const IPC::Message& message, OnCheckNotificationPermission) IPC_MESSAGE_HANDLER(ChildProcessHostMsg_SyncAllocateSharedMemory, OnAllocateSharedMemory) -#if defined(OS_MACOSX) +#if defined(OS_POSIX) && !defined(TOOLKIT_GTK) && !defined(OS_ANDROID) IPC_MESSAGE_HANDLER(ViewHostMsg_AllocTransportDIB, OnAllocTransportDIB) IPC_MESSAGE_HANDLER(ViewHostMsg_FreeTransportDIB, OnFreeTransportDIB) #endif @@ -867,7 +867,7 @@ net::URLRequestContext* RenderMessageFilter::GetRequestContextForURL( return context; } -#if defined(OS_MACOSX) +#if defined(OS_POSIX) && !defined(TOOLKIT_GTK) && !defined(OS_ANDROID) void RenderMessageFilter::OnAllocTransportDIB( size_t size, bool cache_in_browser, TransportDIB::Handle* handle) { render_widget_helper_->AllocTransportDIB(size, cache_in_browser, handle); diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 5001db1632..499f161622 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc @@ -75,6 +75,7 @@ #include "content/browser/renderer_host/media/media_stream_dispatcher_host.h" #include "content/browser/renderer_host/media/peer_connection_tracker_host.h" #include "content/browser/renderer_host/media/video_capture_host.h" +#include "content/browser/renderer_host/memory_benchmark_message_filter.h" #include "content/browser/renderer_host/p2p/socket_dispatcher_host.h" #include "content/browser/renderer_host/pepper/pepper_message_filter.h" #include "content/browser/renderer_host/quota_dispatcher_host.h" @@ -123,7 +124,7 @@ #include "ppapi/shared_impl/ppapi_switches.h" #include "ui/base/ui_base_switches.h" #include "ui/gl/gl_switches.h" -#include "webkit/fileapi/sandbox_mount_point_provider.h" +#include "webkit/browser/fileapi/sandbox_mount_point_provider.h" #include "webkit/glue/resource_type.h" #include "webkit/plugins/plugin_switches.h" @@ -697,6 +698,11 @@ void RenderProcessHostImpl::CreateMessageFilters() { #if defined(ENABLE_WEBRTC) channel_->AddFilter(new WebRtcLoggingHandlerHost()); #endif +#if defined(USE_TCMALLOC) && (defined(OS_LINUX) || defined(OS_ANDROID)) + if (CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableMemoryBenchmarking)) + channel_->AddFilter(new MemoryBenchmarkMessageFilter()); +#endif } int RenderProcessHostImpl::GetNextRoutingID() { @@ -840,6 +846,9 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer( #else switches::kDisableWebAudio, #endif +#if defined(ENABLE_WEBRTC) + switches::kEnableSCTPDataChannels, +#endif switches::kEnableWebMIDI, switches::kEnableExperimentalCanvasFeatures, switches::kEnableExperimentalWebSocket, @@ -864,7 +873,11 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer( switches::kEnableTouchEditing, switches::kEnableVsyncNotification, switches::kEnableWebPInAcceptHeader, +#if defined(ENABLE_WEBRTC) + switches::kEnableWebRtcAecRecordings, +#endif switches::kDisableWebKitMediaSource, + switches::kEnableOverscrollNotifications, switches::kEnableStrictSiteIsolation, switches::kDisableFullScreen, switches::kEnableNewDialogStyle, @@ -886,7 +899,8 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer( switches::kEnableCompositingForFixedPosition, switches::kEnableHighDpiCompositingForFixedPosition, switches::kDisableCompositingForFixedPosition, - switches::kEnableAcceleratedPainting, + switches::kEnableCompositingForTransition, + switches::kDisableCompositingForTransition, switches::kDisableThreadedCompositing, switches::kDisableTouchAdjustment, switches::kDefaultTileWidth, @@ -917,6 +931,7 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer( #endif switches::kNoReferrers, switches::kNoSandbox, + switches::kEnableVtune, switches::kPpapiInProcess, switches::kRegisterPepperPlugins, switches::kRendererAssertTest, @@ -949,15 +964,14 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer( cc::switches::kEnableImplSidePainting, cc::switches::kEnablePartialSwap, cc::switches::kEnablePerTilePainting, - cc::switches::kEnablePinchZoomScrollbars, - cc::switches::kDisablePinchZoomScrollbars, - cc::switches::kEnablePredictionBenchmarking, + cc::switches::kEnablePinchVirtualViewport, cc::switches::kEnableRightAlignedScheduling, cc::switches::kEnableTopControlsPositionCalculation, + cc::switches::kForceDirectLayerDrawing, cc::switches::kLowResolutionContentsScaleFactor, + cc::switches::kMaxTilesForInterestArea, cc::switches::kMaxUnusedResourceMemoryUsagePercentage, cc::switches::kNumRasterThreads, - cc::switches::kMaxTilesForInterestArea, cc::switches::kShowCompositedLayerBorders, cc::switches::kShowCompositedLayerTree, cc::switches::kShowFPSCounter, @@ -972,8 +986,8 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer( cc::switches::kTopControlsHeight, cc::switches::kTopControlsHideThreshold, cc::switches::kTopControlsShowThreshold, - cc::switches::kTraceAllRenderedFrames, cc::switches::kTraceOverdraw, + cc::switches::kUseMapImage, }; renderer_cmd->CopySwitchesFrom(browser_cmd, kSwitchNames, arraysize(kSwitchNames)); @@ -1047,7 +1061,7 @@ TransportDIB* RenderProcessHostImpl::MapTransportDIB( STANDARD_RIGHTS_REQUIRED | FILE_MAP_READ | FILE_MAP_WRITE, FALSE, 0); return TransportDIB::Map(section); -#elif defined(TOOLKIT_GTK) || (defined(OS_LINUX) && defined(USE_AURA)) +#elif defined(TOOLKIT_GTK) return TransportDIB::Map(dib_id.shmkey); #elif defined(OS_ANDROID) return TransportDIB::Map(dib_id); @@ -1087,7 +1101,7 @@ TransportDIB* RenderProcessHostImpl::GetTransportDIB( } } -#if defined(TOOLKIT_GTK) || (defined(OS_LINUX) && defined(USE_AURA)) +#if defined(TOOLKIT_GTK) smallest_iterator->second->Detach(); #else delete smallest_iterator->second; @@ -1101,7 +1115,7 @@ TransportDIB* RenderProcessHostImpl::GetTransportDIB( } void RenderProcessHostImpl::ClearTransportDIBCache() { -#if defined(TOOLKIT_GTK) || (defined(OS_LINUX) && defined(USE_AURA)) +#if defined(TOOLKIT_GTK) std::map<TransportDIB::Id, TransportDIB*>::const_iterator dib = cached_dibs_.begin(); for (; dib != cached_dibs_.end(); ++dib) @@ -1749,17 +1763,13 @@ void RenderProcessHostImpl::OnSavedPageAsMHTML(int job_id, int64 data_size) { } void RenderProcessHostImpl::OnCompositorSurfaceBuffersSwappedNoHost( - int32 surface_id, - uint64 surface_handle, - int32 route_id, - const gfx::Size& size, - int32 gpu_process_host_id) { + const ViewHostMsg_CompositorSurfaceBuffersSwapped_Params& params) { TRACE_EVENT0("renderer_host", "RenderWidgetHostImpl::OnCompositorSurfaceBuffersSwappedNoHost"); AcceleratedSurfaceMsg_BufferPresented_Params ack_params; ack_params.sync_point = 0; - RenderWidgetHostImpl::AcknowledgeBufferPresent(route_id, - gpu_process_host_id, + RenderWidgetHostImpl::AcknowledgeBufferPresent(params.route_id, + params.gpu_process_host_id, ack_params); } diff --git a/content/browser/renderer_host/render_process_host_impl.h b/content/browser/renderer_host/render_process_host_impl.h index 773ebc5717..dff4959945 100644 --- a/content/browser/renderer_host/render_process_host_impl.h +++ b/content/browser/renderer_host/render_process_host_impl.h @@ -20,6 +20,7 @@ #include "ui/surface/transport_dib.h" class CommandLine; +struct ViewHostMsg_CompositorSurfaceBuffersSwapped_Params; namespace base { class MessageLoop; @@ -215,11 +216,8 @@ class CONTENT_EXPORT RenderProcessHostImpl void OnSavedPageAsMHTML(int job_id, int64 mhtml_file_size); // CompositorSurfaceBuffersSwapped handler when there's no RWH. - void OnCompositorSurfaceBuffersSwappedNoHost(int32 surface_id, - uint64 surface_handle, - int32 route_id, - const gfx::Size& size, - int32 gpu_process_host_id); + void OnCompositorSurfaceBuffersSwappedNoHost( + const ViewHostMsg_CompositorSurfaceBuffersSwapped_Params& params); // Generates a command line to be used to spawn a renderer and appends the // results to |*command_line|. diff --git a/content/browser/renderer_host/render_view_host_browsertest.cc b/content/browser/renderer_host/render_view_host_browsertest.cc index 1170fe5131..8fb43e567f 100644 --- a/content/browser/renderer_host/render_view_host_browsertest.cc +++ b/content/browser/renderer_host/render_view_host_browsertest.cc @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/path_service.h" #include "base/time.h" #include "base/utf_string_conversions.h" #include "base/values.h" @@ -10,13 +11,14 @@ #include "content/common/view_messages.h" #include "content/public/browser/notification_types.h" #include "content/public/browser/web_contents_observer.h" +#include "content/public/common/content_paths.h" #include "content/public/test/browser_test_utils.h" #include "content/shell/shell.h" #include "content/test/content_browser_test.h" #include "content/test/content_browser_test_utils.h" #include "net/base/host_port_pair.h" #include "net/base/net_util.h" -#include "net/test/spawned_test_server/spawned_test_server.h" +#include "net/test/embedded_test_server/embedded_test_server.h" namespace content { @@ -59,30 +61,33 @@ class RenderViewHostTestWebContentsObserver : public WebContentsObserver { }; IN_PROC_BROWSER_TEST_F(RenderViewHostTest, FrameNavigateSocketAddress) { - ASSERT_TRUE(test_server()->Start()); + ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); RenderViewHostTestWebContentsObserver observer(shell()->web_contents()); - GURL test_url = test_server()->GetURL("files/simple_page.html"); + GURL test_url = embedded_test_server()->GetURL("/simple_page.html"); NavigateToURL(shell(), test_url); - EXPECT_EQ(test_server()->host_port_pair().ToString(), + EXPECT_EQ(net::HostPortPair::FromURL( + embedded_test_server()->base_url()).ToString(), observer.observed_socket_address().ToString()); EXPECT_EQ(1, observer.navigation_count()); } IN_PROC_BROWSER_TEST_F(RenderViewHostTest, BaseURLParam) { - ASSERT_TRUE(test_server()->Start()); + ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); RenderViewHostTestWebContentsObserver observer(shell()->web_contents()); // Base URL is not set if it is the same as the URL. - GURL test_url = test_server()->GetURL("files/simple_page.tml"); + GURL test_url = embedded_test_server()->GetURL("/simple_page.html"); NavigateToURL(shell(), test_url); EXPECT_TRUE(observer.base_url().is_empty()); EXPECT_EQ(1, observer.navigation_count()); // But should be set to the original page when reading MHTML. - test_url = net::FilePathToFileURL(test_server()->document_root().Append( - FILE_PATH_LITERAL("google.mht"))); + base::FilePath content_test_data_dir; + ASSERT_TRUE(PathService::Get(DIR_TEST_DATA, &content_test_data_dir)); + test_url = net::FilePathToFileURL( + content_test_data_dir.AppendASCII("google.mht")); NavigateToURL(shell(), test_url); EXPECT_EQ("http://www.google.com/", observer.base_url().spec()); } diff --git a/content/browser/renderer_host/render_view_host_delegate.h b/content/browser/renderer_host/render_view_host_delegate.h index f2be7e15ed..d9ad8efd89 100644 --- a/content/browser/renderer_host/render_view_host_delegate.h +++ b/content/browser/renderer_host/render_view_host_delegate.h @@ -47,6 +47,7 @@ class Size; namespace content { class BrowserContext; +class PageState; class RenderViewHost; class RenderViewHostDelegateView; class SessionStorageNamespace; @@ -170,7 +171,7 @@ class CONTENT_EXPORT RenderViewHostDelegate { // The state for the page changed and should be updated. virtual void UpdateState(RenderViewHost* render_view_host, int32 page_id, - const std::string& state) {} + const PageState& state) {} // The page's title was changed and should be updated. virtual void UpdateTitle(RenderViewHost* render_view_host, diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc index b34ce2bafc..4ab78219b0 100644 --- a/content/browser/renderer_host/render_view_host_impl.cc +++ b/content/browser/renderer_host/render_view_host_impl.cc @@ -59,6 +59,7 @@ #include "content/public/common/context_menu_source_type.h" #include "content/public/common/result_codes.h" #include "content/public/common/url_constants.h" +#include "content/public/common/url_utils.h" #include "net/base/net_util.h" #include "net/url_request/url_request_context_getter.h" #include "third_party/skia/include/core/SkBitmap.h" @@ -66,8 +67,7 @@ #include "ui/gfx/native_widget_types.h" #include "ui/shell_dialogs/selected_file_info.h" #include "ui/snapshot/snapshot.h" -#include "webkit/fileapi/isolated_context.h" -#include "webkit/glue/glue_serialize.h" +#include "webkit/browser/fileapi/isolated_context.h" #include "webkit/glue/webdropdata.h" #include "webkit/glue/webkit_glue.h" @@ -77,7 +77,7 @@ #elif defined(OS_MACOSX) #include "content/browser/renderer_host/popup_menu_helper_mac.h" #elif defined(OS_ANDROID) -#include "content/browser/android/media_player_manager_impl.h" +#include "media/base/android/media_player_manager.h" #endif using base::TimeDelta; @@ -197,7 +197,7 @@ RenderViewHostImpl::RenderViewHostImpl( g_created_callbacks.Get().at(i).Run(this); #if defined(OS_ANDROID) - media_player_manager_ = new MediaPlayerManagerImpl(this); + media_player_manager_ = media::MediaPlayerManager::Create(this); #endif } @@ -1207,7 +1207,7 @@ void RenderViewHostImpl::OnNavigate(const IPC::Message& msg) { // should be killed. if (!CanCommitURL(validated_params.url)) { VLOG(1) << "Blocked URL " << validated_params.url.spec(); - validated_params.url = GURL(chrome::kAboutBlankURL); + validated_params.url = GURL(kAboutBlankURL); RecordAction(UserMetricsAction("CanCommitURL_BlockedAndKilled")); // Kills the process. process->ReceivedBadMessage(); @@ -1234,7 +1234,7 @@ void RenderViewHostImpl::OnNavigate(const IPC::Message& msg) { // Without this check, the renderer can trick the browser into using // filenames it can't access in a future session restore. - if (!CanAccessFilesOfSerializedState(validated_params.content_state)) { + if (!CanAccessFilesOfPageState(validated_params.page_state)) { GetProcess()->ReceivedBadMessage(); return; } @@ -1242,11 +1242,10 @@ void RenderViewHostImpl::OnNavigate(const IPC::Message& msg) { delegate_->DidNavigate(this, validated_params); } -void RenderViewHostImpl::OnUpdateState(int32 page_id, - const std::string& state) { +void RenderViewHostImpl::OnUpdateState(int32 page_id, const PageState& state) { // Without this check, the renderer can trick the browser into using // filenames it can't access in a future session restore. - if (!CanAccessFilesOfSerializedState(state)) { + if (!CanAccessFilesOfPageState(state)) { GetProcess()->ReceivedBadMessage(); return; } @@ -1725,7 +1724,7 @@ void RenderViewHostImpl::FilterURL(ChildProcessSecurityPolicyImpl* policy, // This is because the browser treats navigation to an empty GURL as a // navigation to the home page. This is often a privileged page // (chrome://newtab/) which is exactly what we don't want. - *url = GURL(chrome::kAboutBlankURL); + *url = GURL(kAboutBlankURL); RecordAction(UserMetricsAction("FilterURLTermiate_Invalid")); return; } @@ -1733,7 +1732,7 @@ void RenderViewHostImpl::FilterURL(ChildProcessSecurityPolicyImpl* policy, if (url->SchemeIs(chrome::kAboutScheme)) { // The renderer treats all URLs in the about: scheme as being about:blank. // Canonicalize about: URLs to about:blank. - *url = GURL(chrome::kAboutBlankURL); + *url = GURL(kAboutBlankURL); RecordAction(UserMetricsAction("FilterURLTermiate_About")); } @@ -1747,7 +1746,7 @@ void RenderViewHostImpl::FilterURL(ChildProcessSecurityPolicyImpl* policy, // URL. This prevents us from storing the blocked URL and becoming confused // later. VLOG(1) << "Blocked URL " << url->spec(); - *url = GURL(chrome::kAboutBlankURL); + *url = GURL(kAboutBlankURL); RecordAction(UserMetricsAction("FilterURLTermiate_Blocked")); } } @@ -2073,12 +2072,12 @@ void RenderViewHostImpl::ClearPowerSaveBlockers() { STLDeleteValues(&power_save_blockers_); } -bool RenderViewHostImpl::CanAccessFilesOfSerializedState( - const std::string& state) const { +bool RenderViewHostImpl::CanAccessFilesOfPageState( + const PageState& state) const { ChildProcessSecurityPolicyImpl* policy = ChildProcessSecurityPolicyImpl::GetInstance(); - const std::vector<base::FilePath>& file_paths = - webkit_glue::FilePathsFromHistoryState(state); + + const std::vector<base::FilePath>& file_paths = state.GetReferencedFiles(); for (std::vector<base::FilePath>::const_iterator file = file_paths.begin(); file != file_paths.end(); ++file) { if (!policy->CanReadFile(GetProcess()->GetID(), *file)) diff --git a/content/browser/renderer_host/render_view_host_impl.h b/content/browser/renderer_host/render_view_host_impl.h index c96e0f3f47..2d5249f6c2 100644 --- a/content/browser/renderer_host/render_view_host_impl.h +++ b/content/browser/renderer_host/render_view_host_impl.h @@ -51,9 +51,16 @@ class Range; struct SelectedFileInfo; } +#if defined(OS_ANDROID) +namespace media { +class MediaPlayerManager; +} +#endif + namespace content { class ChildProcessSecurityPolicyImpl; +class PageState; class PowerSaveBlocker; class RenderViewHostObserver; class RenderWidgetHostDelegate; @@ -65,10 +72,6 @@ struct FileChooserParams; struct Referrer; struct ShowDesktopNotificationHostMsgParams; -#if defined(OS_ANDROID) -class MediaPlayerManagerImpl; -#endif - #if defined(COMPILER_MSVC) // RenderViewHostImpl is the bottom of a diamond-shaped hierarchy, // with RenderWidgetHost at the root. VS warns when methods from the @@ -378,7 +381,7 @@ class CONTENT_EXPORT RenderViewHostImpl #endif #if defined(OS_ANDROID) - MediaPlayerManagerImpl* media_player_manager() { + media::MediaPlayerManager* media_player_manager() { return media_player_manager_; } @@ -479,7 +482,7 @@ class CONTENT_EXPORT RenderViewHostImpl void OnDidFailProvisionalLoadWithError( const ViewHostMsg_DidFailProvisionalLoadWithError_Params& params); void OnNavigate(const IPC::Message& msg); - void OnUpdateState(int32 page_id, const std::string& state); + void OnUpdateState(int32 page_id, const PageState& state); void OnUpdateTitle(int32 page_id, const string16& title, WebKit::WebTextDirection title_direction); @@ -571,7 +574,7 @@ class CONTENT_EXPORT RenderViewHostImpl void ClearPowerSaveBlockers(); - bool CanAccessFilesOfSerializedState(const std::string& state) const; + bool CanAccessFilesOfPageState(const PageState& state) const; // Our delegate, which wants to know about changes in the RenderView. RenderViewHostDelegate* delegate_; @@ -688,7 +691,7 @@ class CONTENT_EXPORT RenderViewHostImpl #if defined(OS_ANDROID) // Manages all the android mediaplayer objects and handling IPCs for video. // This class inherits from RenderViewHostObserver. - MediaPlayerManagerImpl* media_player_manager_; + media::MediaPlayerManager* media_player_manager_; #endif DISALLOW_COPY_AND_ASSIGN(RenderViewHostImpl); diff --git a/content/browser/renderer_host/render_view_host_manager_browsertest.cc b/content/browser/renderer_host/render_view_host_manager_browsertest.cc index 9000c69823..e94fa9abc6 100644 --- a/content/browser/renderer_host/render_view_host_manager_browsertest.cc +++ b/content/browser/renderer_host/render_view_host_manager_browsertest.cc @@ -20,6 +20,7 @@ #include "content/public/browser/render_process_host.h" #include "content/public/browser/render_view_host_observer.h" #include "content/public/browser/web_contents.h" +#include "content/public/browser/web_contents_observer.h" #include "content/public/common/url_constants.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/test_utils.h" @@ -313,6 +314,28 @@ IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, EXPECT_EQ(orig_site_instance, noref_site_instance); } +namespace { + +class WebContentsDestroyedObserver : public WebContentsObserver { + public: + WebContentsDestroyedObserver(WebContents* web_contents, + const base::Closure& callback) + : WebContentsObserver(web_contents), + callback_(callback) { + } + + virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE { + callback_.Run(); + } + + private: + base::Closure callback_; + + DISALLOW_COPY_AND_ASSIGN(WebContentsDestroyedObserver); +}; + +} // namespace + // Test for crbug.com/116192. Targeted links should still work after the // named target window has swapped processes. IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, @@ -386,15 +409,15 @@ IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, NavigateToURL(new_shell, https_server.GetURL("files/title1.html")); EXPECT_EQ(new_site_instance, new_shell->web_contents()->GetSiteInstance()); - WindowedNotificationObserver close_observer( - NOTIFICATION_WEB_CONTENTS_DESTROYED, - Source<WebContents>(new_shell->web_contents())); + scoped_refptr<MessageLoopRunner> loop_runner(new MessageLoopRunner); + WebContentsDestroyedObserver close_observer(new_shell->web_contents(), + loop_runner->QuitClosure()); EXPECT_TRUE(ExecuteScriptAndExtractBool( shell()->web_contents(), "window.domAutomationController.send(testCloseWindow());", &success)); EXPECT_TRUE(success); - close_observer.Wait(); + loop_runner->Run(); } // Test that setting the opener to null in a window affects cross-process @@ -839,7 +862,7 @@ IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, ClickLinkAfter204Error) { // do not cause back/forward navigations to be considered stale by the // renderer. IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, BackForwardNotStale) { - NavigateToURL(shell(), GURL(chrome::kAboutBlankURL)); + NavigateToURL(shell(), GURL(kAboutBlankURL)); // Start two servers with different sites. ASSERT_TRUE(test_server()->Start()); diff --git a/content/browser/renderer_host/render_widget_helper.cc b/content/browser/renderer_host/render_widget_helper.cc index 1a3231d9d3..d244da7538 100644 --- a/content/browser/renderer_host/render_widget_helper.cc +++ b/content/browser/renderer_host/render_widget_helper.cc @@ -97,7 +97,7 @@ RenderWidgetHelper::~RenderWidgetHelper() { // object, so we should not be destroyed unless pending_paints_ is empty! DCHECK(pending_paints_.empty()); -#if defined(OS_MACOSX) +#if defined(OS_POSIX) && !defined(TOOLKIT_GTK) && !defined(OS_ANDROID) ClearAllocatedDIBs(); #endif } @@ -335,7 +335,7 @@ void RenderWidgetHelper::OnCreateFullscreenWidgetOnUI(int opener_id, host->CreateNewFullscreenWidget(route_id); } -#if defined(OS_MACOSX) +#if defined(OS_POSIX) && !defined(TOOLKIT_GTK) && !defined(OS_ANDROID) TransportDIB* RenderWidgetHelper::MapTransportDIB(TransportDIB::Id dib_id) { base::AutoLock locked(allocated_dibs_lock_); diff --git a/content/browser/renderer_host/render_widget_helper.h b/content/browser/renderer_host/render_widget_helper.h index 01afc03fbe..733130af2a 100644 --- a/content/browser/renderer_host/render_widget_helper.h +++ b/content/browser/renderer_host/render_widget_helper.h @@ -133,7 +133,7 @@ class RenderWidgetHelper // created by CreateNewWindow which initially blocked the requests. void ResumeRequestsForView(int route_id); -#if defined(OS_MACOSX) +#if defined(OS_POSIX) && !defined(TOOLKIT_GTK) && !defined(OS_ANDROID) // Given the id of a transport DIB, return a mapping to it or NULL on error. TransportDIB* MapTransportDIB(TransportDIB::Id dib_id); #endif @@ -156,7 +156,7 @@ class RenderWidgetHelper int* surface_id); void CreateNewFullscreenWidget(int opener_id, int* route_id, int* surface_id); -#if defined(OS_MACOSX) +#if defined(OS_POSIX) // Called on the IO thread to handle the allocation of a TransportDIB. If // |cache_in_browser| is |true|, then a copy of the shmem is kept by the // browser, and it is the caller's repsonsibility to call @@ -213,11 +213,11 @@ class RenderWidgetHelper // not received as expected. void OnSimulateSwapOutACK(const ViewMsg_SwapOut_Params& params); -#if defined(OS_MACOSX) +#if defined(OS_POSIX) // Called on destruction to release all allocated transport DIBs void ClearAllocatedDIBs(); - // On OSX we keep file descriptors to all the allocated DIBs around until + // On POSIX we keep file descriptors to all the allocated DIBs around until // the renderer frees them. base::Lock allocated_dibs_lock_; std::map<TransportDIB::Id, int> allocated_dibs_; diff --git a/content/browser/renderer_host/render_widget_host_delegate.h b/content/browser/renderer_host/render_widget_host_delegate.h index fa41727e35..9e8d36ea09 100644 --- a/content/browser/renderer_host/render_widget_host_delegate.h +++ b/content/browser/renderer_host/render_widget_host_delegate.h @@ -46,6 +46,9 @@ class CONTENT_EXPORT RenderWidgetHostDelegate { // Returns true if the |event| was handled. virtual bool PreHandleWheelEvent(const WebKit::WebMouseWheelEvent& event); + // Notifies that screen rects were sent to renderer process. + virtual void DidSendScreenRects(RenderWidgetHostImpl* rwh) {} + #if defined(OS_WIN) && defined(USE_AURA) // Returns the widget's parent's NativeViewAccessible. virtual gfx::NativeViewAccessible GetParentNativeViewAccessible(); diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc index b06d74943f..5cb74b81de 100644 --- a/content/browser/renderer_host/render_widget_host_impl.cc +++ b/content/browser/renderer_host/render_widget_host_impl.cc @@ -147,6 +147,7 @@ RenderWidgetHostImpl::RenderWidgetHostImpl(RenderWidgetHostDelegate* delegate, is_accelerated_compositing_active_(false), repaint_ack_pending_(false), resize_ack_pending_(false), + screen_info_out_of_date_(false), overdraw_bottom_height_(0.f), should_auto_resize_(false), waiting_for_screen_rects_ack_(false), @@ -318,6 +319,8 @@ void RenderWidgetHostImpl::SendScreenRects() { last_window_screen_rect_ = view_->GetBoundsInRootWindow(); Send(new ViewMsg_UpdateScreenRects( GetRoutingID(), last_view_screen_rect_, last_window_screen_rect_)); + if (delegate_) + delegate_->DidSendScreenRects(this); waiting_for_screen_rects_ack_ = true; } @@ -388,6 +391,7 @@ bool RenderWidgetHostImpl::OnMessageReceived(const IPC::Message &msg) { OnCompositorSurfaceBuffersSwapped) IPC_MESSAGE_HANDLER_GENERIC(ViewHostMsg_SwapCompositorFrame, msg_is_ok = OnSwapCompositorFrame(msg)) + IPC_MESSAGE_HANDLER(ViewHostMsg_DidOverscroll, OnOverscrolled) IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateRect, OnUpdateRect) IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateIsDelayed, OnUpdateIsDelayed) IPC_MESSAGE_HANDLER(InputHostMsg_HandleInputEvent_ACK, OnInputEventAck) @@ -523,6 +527,7 @@ void RenderWidgetHostImpl::WasResized() { bool size_changed = new_size != current_size_; bool side_payload_changed = + screen_info_out_of_date_ || old_physical_backing_size != physical_backing_size_ || was_fullscreen != is_fullscreen_ || old_overdraw_bottom_height != overdraw_bottom_height_; @@ -534,14 +539,24 @@ void RenderWidgetHostImpl::WasResized() { !side_payload_changed) return; - // We don't expect to receive an ACK when the requested size is empty or when - // the main viewport size didn't change. - if (!new_size.IsEmpty() && size_changed) + if (!screen_info_) { + screen_info_.reset(new WebKit::WebScreenInfo); + GetWebScreenInfo(screen_info_.get()); + } + + // We don't expect to receive an ACK when the requested size or the physical + // backing size is empty, or when the main viewport size didn't change. + if (!new_size.IsEmpty() && !physical_backing_size_.IsEmpty() && size_changed) resize_ack_pending_ = true; - if (!Send(new ViewMsg_Resize(routing_id_, new_size, physical_backing_size_, - overdraw_bottom_height_, - GetRootWindowResizerRect(), is_fullscreen_))) { + ViewMsg_Resize_Params params; + params.screen_info = *screen_info_; + params.new_size = new_size; + params.physical_backing_size = physical_backing_size_; + params.overdraw_bottom_height = overdraw_bottom_height_; + params.resizer_rect = GetRootWindowResizerRect(); + params.is_fullscreen = is_fullscreen_; + if (!Send(new ViewMsg_Resize(routing_id_, params))) { resize_ack_pending_ = false; } else { in_flight_size_ = new_size; @@ -982,7 +997,7 @@ void RenderWidgetHostImpl::ForwardWheelEvent( void RenderWidgetHostImpl::ForwardWheelEventWithLatencyInfo( const WebMouseWheelEvent& wheel_event, - const cc::LatencyInfo& latency_info) { + const ui::LatencyInfo& latency_info) { TRACE_EVENT0("renderer_host", "RenderWidgetHostImpl::ForwardWheelEventWithLatencyInfo"); if (ignore_input_events_ || process_->IgnoreInputEvents()) @@ -1045,7 +1060,7 @@ void RenderWidgetHostImpl::ForwardGestureEvent( if (ignore_input_events_ || process_->IgnoreInputEvents()) return; - cc::LatencyInfo latency_info = NewInputLatencyInfo(); + ui::LatencyInfo latency_info = NewInputLatencyInfo(); if (!IsInOverscrollGesture() && !gesture_event_filter_->ShouldForward( @@ -1200,16 +1215,17 @@ int64 RenderWidgetHostImpl::GetLatencyComponentId() { return GetRoutingID() | (static_cast<int64>(GetProcess()->GetID()) << 32); } -cc::LatencyInfo RenderWidgetHostImpl::NewInputLatencyInfo() { - cc::LatencyInfo info; - info.AddLatencyNumber( - cc::kInputEvent, GetLatencyComponentId(), ++last_input_number_); +ui::LatencyInfo RenderWidgetHostImpl::NewInputLatencyInfo() { + ui::LatencyInfo info; + info.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_COMPONENT, + GetLatencyComponentId(), + ++last_input_number_); return info; } void RenderWidgetHostImpl::SendInputEvent(const WebInputEvent& input_event, int event_size, - const cc::LatencyInfo& latency_info, + const ui::LatencyInfo& latency_info, bool is_keyboard_shortcut) { input_event_start_time_ = TimeTicks::Now(); Send(new InputMsg_HandleInputEvent( @@ -1219,7 +1235,7 @@ void RenderWidgetHostImpl::SendInputEvent(const WebInputEvent& input_event, void RenderWidgetHostImpl::ForwardInputEvent( const WebInputEvent& input_event, int event_size, - const cc::LatencyInfo& latency_info, bool is_keyboard_shortcut) { + const ui::LatencyInfo& latency_info, bool is_keyboard_shortcut) { TRACE_EVENT0("renderer_host", "RenderWidgetHostImpl::ForwardInputEvent"); if (!process_->HasConnection()) @@ -1330,9 +1346,12 @@ const NativeWebKeyboardEvent* } void RenderWidgetHostImpl::NotifyScreenInfoChanged() { - WebKit::WebScreenInfo screen_info; - GetWebScreenInfo(&screen_info); - Send(new ViewMsg_ScreenInfoChanged(GetRoutingID(), screen_info)); + // The resize message (which may not happen immediately) will carry with it + // the screen info as well as the new size (if the screen has changed scale + // factor). + screen_info_.reset(); + screen_info_out_of_date_ = true; + WasResized(); } void RenderWidgetHostImpl::GetSnapshotFromRenderer( @@ -1344,7 +1363,7 @@ void RenderWidgetHostImpl::GetSnapshotFromRenderer( gfx::Rect copy_rect = src_subrect.IsEmpty() ? gfx::Rect(view_->GetViewBounds().size()) : src_subrect; - gfx::Rect copy_rect_in_pixel = ConvertRectToPixel(view_, copy_rect); + gfx::Rect copy_rect_in_pixel = ConvertViewRectToPixel(view_, copy_rect); Send(new ViewMsg_Snapshot(GetRoutingID(), copy_rect_in_pixel)); } @@ -1644,28 +1663,25 @@ void RenderWidgetHostImpl::OnPaintAtSizeAck(int tag, const gfx::Size& size) { } void RenderWidgetHostImpl::OnCompositorSurfaceBuffersSwapped( - int32 surface_id, - uint64 surface_handle, - int32 route_id, - const gfx::Size& size, - int32 gpu_process_host_id) { + const ViewHostMsg_CompositorSurfaceBuffersSwapped_Params& params) { TRACE_EVENT0("renderer_host", "RenderWidgetHostImpl::OnCompositorSurfaceBuffersSwapped"); if (!view_) { AcceleratedSurfaceMsg_BufferPresented_Params ack_params; ack_params.sync_point = 0; - RenderWidgetHostImpl::AcknowledgeBufferPresent(route_id, - gpu_process_host_id, + RenderWidgetHostImpl::AcknowledgeBufferPresent(params.route_id, + params.gpu_process_host_id, ack_params); return; } GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params gpu_params; - gpu_params.surface_id = surface_id; - gpu_params.surface_handle = surface_handle; - gpu_params.route_id = route_id; - gpu_params.size = size; + gpu_params.surface_id = params.surface_id; + gpu_params.surface_handle = params.surface_handle; + gpu_params.route_id = params.route_id; + gpu_params.size = params.size; + gpu_params.scale_factor = params.scale_factor; view_->AcceleratedSurfaceBuffersSwapped(gpu_params, - gpu_process_host_id); + params.gpu_process_host_id); } bool RenderWidgetHostImpl::OnSwapCompositorFrame( @@ -1693,6 +1709,13 @@ bool RenderWidgetHostImpl::OnSwapCompositorFrame( return true; } +void RenderWidgetHostImpl::OnOverscrolled( + gfx::Vector2dF accumulated_overscroll, + gfx::Vector2dF current_fling_velocity) { + if (view_) + view_->OnOverscrolled(accumulated_overscroll, current_fling_velocity); +} + void RenderWidgetHostImpl::OnUpdateRect( const ViewHostMsg_UpdateRect_Params& params) { TRACE_EVENT0("renderer_host", "RenderWidgetHostImpl::OnUpdateRect"); @@ -2306,6 +2329,12 @@ void RenderWidgetHostImpl::FatalAccessibilityTreeError() { } #if defined(OS_WIN) && defined(USE_AURA) +void RenderWidgetHostImpl::SetParentNativeViewAccessible( + gfx::NativeViewAccessible accessible_parent) { + if (view_) + view_->SetParentNativeViewAccessible(accessible_parent); +} + gfx::NativeViewAccessible RenderWidgetHostImpl::GetParentNativeViewAccessible() const { return delegate_->GetParentNativeViewAccessible(); @@ -2472,7 +2501,7 @@ void RenderWidgetHostImpl::DetachDelegate() { delegate_ = NULL; } -void RenderWidgetHostImpl::FrameSwapped(const cc::LatencyInfo& latency_info) { +void RenderWidgetHostImpl::FrameSwapped(const ui::LatencyInfo& latency_info) { } } // namespace content diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h index 5c556555b0..0d67af1cd5 100644 --- a/content/browser/renderer_host/render_widget_host_impl.h +++ b/content/browser/renderer_host/render_widget_host_impl.h @@ -23,7 +23,6 @@ #include "base/time.h" #include "base/timer.h" #include "build/build_config.h" -#include "cc/debug/latency_info.h" #include "content/browser/renderer_host/event_with_latency_info.h" #include "content/browser/renderer_host/smooth_scroll_gesture_controller.h" #include "content/common/view_message_enums.h" @@ -32,10 +31,12 @@ #include "content/public/common/page_zoom.h" #include "ipc/ipc_listener.h" #include "ui/base/ime/text_input_type.h" +#include "ui/base/latency_info.h" #include "ui/gfx/native_widget_types.h" class WebCursor; struct AcceleratedSurfaceMsg_BufferPresented_Params; +struct ViewHostMsg_CompositorSurfaceBuffersSwapped_Params; struct ViewHostMsg_UpdateRect_Params; struct ViewHostMsg_TextInputState_Params; struct ViewHostMsg_BeginSmoothScroll_Params; @@ -382,6 +383,8 @@ class CONTENT_EXPORT RenderWidgetHostImpl : virtual public RenderWidgetHost, void FatalAccessibilityTreeError(); #if defined(OS_WIN) && defined(USE_AURA) + void SetParentNativeViewAccessible( + gfx::NativeViewAccessible accessible_parent); gfx::NativeViewAccessible GetParentNativeViewAccessible() const; #endif @@ -476,7 +479,7 @@ class CONTENT_EXPORT RenderWidgetHostImpl : virtual public RenderWidgetHost, // other way around. bool should_auto_resize() { return should_auto_resize_; } - void FrameSwapped(const cc::LatencyInfo& latency_info); + void FrameSwapped(const ui::LatencyInfo& latency_info); // Returns the ID that uniquely describes this component to the latency // subsystem. @@ -488,12 +491,12 @@ class CONTENT_EXPORT RenderWidgetHostImpl : virtual public RenderWidgetHost, // Transmits the given input event. This is an internal helper for // |ForwardInputEvent()| and should not be used directly from elsewhere. void SendInputEvent(const WebKit::WebInputEvent& input_event, - int event_size, const cc::LatencyInfo& latency_info, + int event_size, const ui::LatencyInfo& latency_info, bool is_keyboard_shortcut); // Internal implementation of the public Forward*Event() methods. void ForwardInputEvent(const WebKit::WebInputEvent& input_event, - int event_size, const cc::LatencyInfo& latency_info, + int event_size, const ui::LatencyInfo& latency_info, bool is_keyboard_shortcut); // Internal forwarding implementations that take a LatencyInfo. @@ -501,10 +504,10 @@ class CONTENT_EXPORT RenderWidgetHostImpl : virtual public RenderWidgetHost, const MouseEventWithLatencyInfo& mouse_event); virtual void ForwardWheelEventWithLatencyInfo( const WebKit::WebMouseWheelEvent& wheel_event, - const cc::LatencyInfo& latency_info); + const ui::LatencyInfo& latency_info); // Create a LatencyInfo struct for a new input event that was just received. - cc::LatencyInfo NewInputLatencyInfo(); + ui::LatencyInfo NewInputLatencyInfo(); // Called when we receive a notification indicating that the renderer // process has gone. This will reset our state so that our state will be @@ -607,12 +610,11 @@ class CONTENT_EXPORT RenderWidgetHostImpl : virtual public RenderWidgetHost, void OnSetTooltipText(const string16& tooltip_text, WebKit::WebTextDirection text_direction_hint); void OnPaintAtSizeAck(int tag, const gfx::Size& size); - void OnCompositorSurfaceBuffersSwapped(int32 surface_id, - uint64 surface_handle, - int32 route_id, - const gfx::Size& size, - int32 gpu_process_host_id); + void OnCompositorSurfaceBuffersSwapped( + const ViewHostMsg_CompositorSurfaceBuffersSwapped_Params& params); bool OnSwapCompositorFrame(const IPC::Message& message); + void OnOverscrolled(gfx::Vector2dF accumulated_overscroll, + gfx::Vector2dF current_fling_velocity); void OnUpdateRect(const ViewHostMsg_UpdateRect_Params& params); void OnUpdateIsDelayed(); void OnInputEventAck(WebKit::WebInputEvent::Type event_type, @@ -736,6 +738,14 @@ class CONTENT_EXPORT RenderWidgetHostImpl : virtual public RenderWidgetHost, // True when waiting for RESIZE_ACK. bool resize_ack_pending_; + // Cached copy of the screen info so that it doesn't need to be updated every + // time the window is resized. + scoped_ptr<WebKit::WebScreenInfo> screen_info_; + + // Set if screen_info_ may have changed and should be recomputed and force a + // resize message. + bool screen_info_out_of_date_; + // The current size of the RenderWidget. gfx::Size current_size_; diff --git a/content/browser/renderer_host/render_widget_host_unittest.cc b/content/browser/renderer_host/render_widget_host_unittest.cc index b28c0ce716..fd0be0a8a2 100644 --- a/content/browser/renderer_host/render_widget_host_unittest.cc +++ b/content/browser/renderer_host/render_widget_host_unittest.cc @@ -492,7 +492,8 @@ class TestView : public TestRenderWidgetHostView { public: explicit TestView(RenderWidgetHostImpl* rwh) : TestRenderWidgetHostView(rwh), - acked_event_count_(0) { + acked_event_count_(0), + use_fake_physical_backing_size_(false) { } // Sets the bounds returned by GetViewBounds. @@ -511,6 +512,14 @@ class TestView : public TestRenderWidgetHostView { return unhandled_wheel_event_; } + void SetMockPhysicalBackingSize(const gfx::Size& mock_physical_backing_size) { + use_fake_physical_backing_size_ = true; + mock_physical_backing_size_ = mock_physical_backing_size; + } + void ClearMockPhysicalBackingSize() { + use_fake_physical_backing_size_ = false; + } + // RenderWidgetHostView override. virtual gfx::Rect GetViewBounds() const OVERRIDE { return bounds_; @@ -523,12 +532,19 @@ class TestView : public TestRenderWidgetHostView { virtual void UnhandledWheelEvent(const WebMouseWheelEvent& event) OVERRIDE { unhandled_wheel_event_ = event; } + virtual gfx::Size GetPhysicalBackingSize() const OVERRIDE { + if (use_fake_physical_backing_size_) + return mock_physical_backing_size_; + return TestRenderWidgetHostView::GetPhysicalBackingSize(); + } protected: WebMouseWheelEvent unhandled_wheel_event_; WebTouchEvent acked_event_; int acked_event_count_; gfx::Rect bounds_; + bool use_fake_physical_backing_size_; + gfx::Size mock_physical_backing_size_; DISALLOW_COPY_AND_ASSIGN(TestView); }; @@ -871,10 +887,20 @@ TEST_F(RenderWidgetHostTest, Resize) { EXPECT_EQ(gfx::Size(), host_->in_flight_size_); EXPECT_FALSE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID)); - // Setting the bounds to a "real" rect should send out the notification. + // Setting the bounds to a "real" rect should send out the notification, + // but should not expect ack for empty physical backing size. gfx::Rect original_size(0, 0, 100, 100); process_->sink().ClearMessages(); view_->set_bounds(original_size); + view_->SetMockPhysicalBackingSize(gfx::Size()); + host_->WasResized(); + EXPECT_FALSE(host_->resize_ack_pending_); + EXPECT_EQ(original_size.size(), host_->in_flight_size_); + EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID)); + + // Setting the bounds to a "real" rect should send out the notification. + process_->sink().ClearMessages(); + view_->ClearMockPhysicalBackingSize(); host_->WasResized(); EXPECT_TRUE(host_->resize_ack_pending_); EXPECT_EQ(original_size.size(), host_->in_flight_size_); @@ -3100,9 +3126,9 @@ TEST_F(RenderWidgetHostTest, WheelScrollEventOverscrolls) { EXPECT_EQ(1U, process_->sink().message_count()); process_->sink().ClearMessages(); - // Receive ACK the first wheel event as processed. + // Receive ACK the first wheel event as not processed. SendInputEventACK(WebInputEvent::MouseWheel, - INPUT_EVENT_ACK_STATE_CONSUMED); + INPUT_EVENT_ACK_STATE_NOT_CONSUMED); EXPECT_EQ(OVERSCROLL_NONE, host_->overscroll_mode()); EXPECT_EQ(OVERSCROLL_NONE, host_->overscroll_delegate()->current_mode()); EXPECT_EQ(1U, process_->sink().message_count()); @@ -3129,6 +3155,75 @@ TEST_F(RenderWidgetHostTest, WheelScrollEventOverscrolls) { EXPECT_EQ(OVERSCROLL_NONE, host_->overscroll_delegate()->current_mode()); } +// Tests that if some scroll events are consumed towards the start, then +// subsequent scrolls do not overscroll. +TEST_F(RenderWidgetHostTest, WheelScrollConsumedDoNotOverscroll) { + host_->SetupForOverscrollControllerTest(); + process_->sink().ClearMessages(); + + // Simulate wheel events. + SimulateWheelEvent(0, -5, 0, true); // sent directly + SimulateWheelEvent(0, -1, 0, true); // enqueued + SimulateWheelEvent(-10, -3, 0, true); // coalesced into previous event + SimulateWheelEvent(-15, -1, 0, true); // coalesced into previous event + SimulateWheelEvent(-30, -3, 0, true); // coalesced into previous event + SimulateWheelEvent(-20, 6, 1, true); // enqueued, different modifiers + EXPECT_EQ(OVERSCROLL_NONE, host_->overscroll_mode()); + EXPECT_EQ(1U, process_->sink().message_count()); + process_->sink().ClearMessages(); + + // Receive ACK the first wheel event as processed. + SendInputEventACK(WebInputEvent::MouseWheel, + INPUT_EVENT_ACK_STATE_CONSUMED); + EXPECT_EQ(OVERSCROLL_NONE, host_->overscroll_mode()); + EXPECT_EQ(OVERSCROLL_NONE, host_->overscroll_delegate()->current_mode()); + EXPECT_EQ(1U, process_->sink().message_count()); + process_->sink().ClearMessages(); + + // Receive ACK for the second (coalesced) event as not processed. This should + // not initiate overscroll, since the beginning of the scroll has been + // consumed. The queued event with different modifiers should be sent to the + // renderer. + SendInputEventACK(WebInputEvent::MouseWheel, + INPUT_EVENT_ACK_STATE_NOT_CONSUMED); + EXPECT_EQ(OVERSCROLL_NONE, host_->overscroll_mode()); + EXPECT_EQ(1U, process_->sink().message_count()); + + process_->sink().ClearMessages(); + SendInputEventACK(WebInputEvent::MouseWheel, + INPUT_EVENT_ACK_STATE_NOT_CONSUMED); + EXPECT_EQ(0U, process_->sink().message_count()); + EXPECT_EQ(OVERSCROLL_NONE, host_->overscroll_mode()); + + // Indicate the end of the scrolling from the touchpad. + SimulateGestureFlingStartEvent(-1200.f, 0.f, WebGestureEvent::Touchpad); + EXPECT_EQ(1U, process_->sink().message_count()); + + // Start another scroll. This time, do not consume any scroll events. + process_->sink().ClearMessages(); + SimulateWheelEvent(0, -5, 0, true); // sent directly + SimulateWheelEvent(0, -1, 0, true); // enqueued + SimulateWheelEvent(-10, -3, 0, true); // coalesced into previous event + SimulateWheelEvent(-15, -1, 0, true); // coalesced into previous event + SimulateWheelEvent(-30, -3, 0, true); // coalesced into previous event + SimulateWheelEvent(-20, 6, 1, true); // enqueued, different modifiers + EXPECT_EQ(OVERSCROLL_NONE, host_->overscroll_mode()); + EXPECT_EQ(1U, process_->sink().message_count()); + process_->sink().ClearMessages(); + + // Receive ACK for the first wheel and the subsequent coalesced event as not + // processed. This should start a back-overscroll. + SendInputEventACK(WebInputEvent::MouseWheel, + INPUT_EVENT_ACK_STATE_NOT_CONSUMED); + EXPECT_EQ(OVERSCROLL_NONE, host_->overscroll_mode()); + EXPECT_EQ(OVERSCROLL_NONE, host_->overscroll_delegate()->current_mode()); + EXPECT_EQ(1U, process_->sink().message_count()); + process_->sink().ClearMessages(); + SendInputEventACK(WebInputEvent::MouseWheel, + INPUT_EVENT_ACK_STATE_NOT_CONSUMED); + EXPECT_EQ(OVERSCROLL_WEST, host_->overscroll_mode()); +} + // Tests that wheel-scrolling correctly turns overscroll on and off. TEST_F(RenderWidgetHostTest, WheelScrollOverscrollToggle) { host_->SetupForOverscrollControllerTest(); @@ -3348,13 +3443,8 @@ TEST_F(RenderWidgetHostTest, GestureScrollOverscrolls) { SimulateGestureEvent(WebInputEvent::GestureScrollBegin, WebGestureEvent::Touchscreen); - SimulateGestureScrollUpdateEvent(8, -5, 0); - - // ACK both events as being processed. SendInputEventACK(WebInputEvent::GestureScrollBegin, - INPUT_EVENT_ACK_STATE_CONSUMED); - SendInputEventACK(WebInputEvent::GestureScrollUpdate, - INPUT_EVENT_ACK_STATE_CONSUMED); + INPUT_EVENT_ACK_STATE_NOT_CONSUMED); EXPECT_EQ(OVERSCROLL_NONE, host_->overscroll_mode()); EXPECT_EQ(OVERSCROLL_NONE, host_->overscroll_delegate()->current_mode()); @@ -3396,6 +3486,36 @@ TEST_F(RenderWidgetHostTest, GestureScrollOverscrolls) { EXPECT_EQ(1U, host_->GestureEventLastQueueEventSize()); } +// Tests that if the page is scrolled because of a scroll-gesture, then that +// particular scroll sequence never generates overscroll, even if there is no +// content to scroll on the page anymore. +TEST_F(RenderWidgetHostTest, GestureScrollConsumedDoNotOverscroll) { + // Turn off debounce handling for test isolation. + host_->SetupForOverscrollControllerTest(); + host_->set_debounce_interval_time_ms(0); + process_->sink().ClearMessages(); + + SimulateGestureEvent(WebInputEvent::GestureScrollBegin, + WebGestureEvent::Touchscreen); + SimulateGestureScrollUpdateEvent(8, -5, 0); + + // ACK both events as being processed. + SendInputEventACK(WebInputEvent::GestureScrollBegin, + INPUT_EVENT_ACK_STATE_CONSUMED); + SendInputEventACK(WebInputEvent::GestureScrollUpdate, + INPUT_EVENT_ACK_STATE_CONSUMED); + EXPECT_EQ(OVERSCROLL_NONE, host_->overscroll_mode()); + EXPECT_EQ(OVERSCROLL_NONE, host_->overscroll_delegate()->current_mode()); + + // Send another gesture event and ACK as not being processed. This should + // not initiate overscroll because the beginning of the scroll event did + // scroll some content on the page. + SimulateGestureScrollUpdateEvent(55, -5, 0); + SendInputEventACK(WebInputEvent::GestureScrollUpdate, + INPUT_EVENT_ACK_STATE_NOT_CONSUMED); + EXPECT_EQ(OVERSCROLL_NONE, host_->overscroll_mode()); +} + // Tests that the overscroll controller plays nice with touch-scrolls and the // gesture event filter with debounce filtering turned on. TEST_F(RenderWidgetHostTest, GestureScrollDebounceOverscrolls) { diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc index 539e7d5411..3ceef322e4 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.cc +++ b/content/browser/renderer_host/render_widget_host_view_android.cc @@ -18,6 +18,7 @@ #include "cc/output/compositor_frame.h" #include "cc/output/compositor_frame_ack.h" #include "content/browser/android/content_view_core_impl.h" +#include "content/browser/android/overscroll_glow.h" #include "content/browser/gpu/gpu_surface_tracker.h" #include "content/browser/renderer_host/compositor_impl_android.h" #include "content/browser/renderer_host/image_transport_factory_android.h" @@ -75,7 +76,7 @@ RenderWidgetHostViewAndroid::RenderWidgetHostViewAndroid( RenderWidgetHostImpl* widget_host, ContentViewCoreImpl* content_view_core) : host_(widget_host), - is_layer_attached_(true), + are_layers_attached_(true), content_view_core_(NULL), ime_adapter_android_(this), cached_background_color_(SK_ColorWHITE), @@ -98,6 +99,11 @@ RenderWidgetHostViewAndroid::RenderWidgetHostViewAndroid( layer_->SetContentsOpaque(true); + if (!CommandLine::ForCurrentProcess()-> + HasSwitch(switches::kDisableOverscrollEdgeEffect)) { + overscroll_effect_ = OverscrollGlow::Create(); + } + host_->SetView(this); SetContentViewCore(content_view_core); } @@ -133,8 +139,8 @@ bool RenderWidgetHostViewAndroid::OnMessageReceived( IPC_MESSAGE_HANDLER(ViewHostMsg_StartContentIntent, OnStartContentIntent) IPC_MESSAGE_HANDLER(ViewHostMsg_DidChangeBodyBackgroundColor, OnDidChangeBodyBackgroundColor) - IPC_MESSAGE_HANDLER(ViewHostMsg_SetVSyncNotificationEnabled, - OnSetVSyncNotificationEnabled) + IPC_MESSAGE_HANDLER(ViewHostMsg_SetNeedsBeginFrame, + OnSetNeedsBeginFrame) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() return handled; @@ -218,7 +224,8 @@ WebKit::WebGLId RenderWidgetHostViewAndroid::GetScaledContentTexture( return helper->CopyAndScaleTexture(texture_id_in_layer_, texture_size_in_layer_, size, - true); + true, + GLHelper::SCALER_QUALITY_FAST); } bool RenderWidgetHostViewAndroid::PopulateBitmapWithContents(jobject jbitmap) { @@ -234,10 +241,12 @@ bool RenderWidgetHostViewAndroid::PopulateBitmapWithContents(jobject jbitmap) { GLHelper* helper = ImageTransportFactoryAndroid::GetInstance()->GetGLHelper(); - WebKit::WebGLId texture = helper->CopyAndScaleTexture(texture_id_in_layer_, - texture_size_in_layer_, - bitmap.size(), - true); + WebKit::WebGLId texture = helper->CopyAndScaleTexture( + texture_id_in_layer_, + texture_size_in_layer_, + bitmap.size(), + true, + GLHelper::SCALER_QUALITY_FAST); if (texture == 0) return false; @@ -292,6 +301,9 @@ void RenderWidgetHostViewAndroid::Blur() { host_->GetRoutingID(), "Unselect", "")); host_->SetInputMethodActive(false); host_->Blur(); + + if (overscroll_effect_) + overscroll_effect_->Finish(); } bool RenderWidgetHostViewAndroid::HasFocus() const { @@ -307,40 +319,32 @@ bool RenderWidgetHostViewAndroid::IsSurfaceAvailableForCopy() const { } void RenderWidgetHostViewAndroid::Show() { - if (is_layer_attached_) + if (are_layers_attached_) return; - is_layer_attached_ = true; - if (content_view_core_) - content_view_core_->AttachLayer(layer_); + are_layers_attached_ = true; + AttachLayers(); } void RenderWidgetHostViewAndroid::Hide() { - if (!is_layer_attached_) + if (!are_layers_attached_) return; - is_layer_attached_ = false; - if (content_view_core_) - content_view_core_->RemoveLayer(layer_); + are_layers_attached_ = false; + RemoveLayers(); } bool RenderWidgetHostViewAndroid::IsShowing() { // ContentViewCoreImpl represents the native side of the Java // ContentViewCore. It being NULL means that it is not attached // to the View system yet, so we treat this RWHVA as hidden. - return is_layer_attached_ && content_view_core_; + return are_layers_attached_ && content_view_core_; } gfx::Rect RenderWidgetHostViewAndroid::GetViewBounds() const { if (!content_view_core_) return gfx::Rect(); - // If the backing hasn't been initialized yet, report empty view bounds - // as well. Otherwise, we may end up stuck in a white-screen state because - // the resize ack is sent after swapbuffers. - if (GetPhysicalBackingSize().IsEmpty()) - return gfx::Rect(); - gfx::Size size = content_view_core_->GetViewportSizeDip(); gfx::Size offset = content_view_core_->GetViewportSizeOffsetDip(); size.Enlarge(-offset.width(), -offset.height()); @@ -403,11 +407,15 @@ void RenderWidgetHostViewAndroid::OnDidChangeBodyBackgroundColor( content_view_core_->OnBackgroundColorChanged(color); } -void RenderWidgetHostViewAndroid::SendVSync(base::TimeTicks frame_time) { - host_->Send(new ViewMsg_DidVSync(host_->GetRoutingID(), frame_time)); +void RenderWidgetHostViewAndroid::SendBeginFrame( + base::TimeTicks frame_time) { + if (host_) + host_->Send(new ViewMsg_BeginFrame(host_->GetRoutingID(), + frame_time)); } -void RenderWidgetHostViewAndroid::OnSetVSyncNotificationEnabled(bool enabled) { +void RenderWidgetHostViewAndroid::OnSetNeedsBeginFrame( + bool enabled) { if (content_view_core_) content_view_core_->SetVSyncNotificationEnabled(enabled); } @@ -440,10 +448,8 @@ void RenderWidgetHostViewAndroid::RenderViewGone( } void RenderWidgetHostViewAndroid::Destroy() { - if (content_view_core_) { - content_view_core_->RemoveLayer(layer_); - content_view_core_ = NULL; - } + RemoveLayers(); + content_view_core_ = NULL; // The RenderWidgetHost's destruction led here, so don't call it. host_ = NULL; @@ -580,6 +586,8 @@ void RenderWidgetHostViewAndroid::ComputeContentsSize( content_size_in_layer_ = gfx::Size(texture_size_in_layer_.width() - offset.x(), texture_size_in_layer_.height() - offset.y()); + // Content size changes should be reflected in associated animation effects. + UpdateAnimationSize(frame); } void RenderWidgetHostViewAndroid::OnSwapCompositorFrame( @@ -693,6 +701,53 @@ void RenderWidgetHostViewAndroid::BuffersSwapped( ack_callbacks_.push(ack_callback); } +void RenderWidgetHostViewAndroid::AttachLayers() { + if (!content_view_core_) + return; + + content_view_core_->AttachLayer(layer_); + + if (overscroll_effect_) + content_view_core_->AttachLayer(overscroll_effect_->root_layer()); +} + +void RenderWidgetHostViewAndroid::RemoveLayers() { + if (!content_view_core_) + return; + + if (overscroll_effect_) + content_view_core_->RemoveLayer(overscroll_effect_->root_layer()); + + content_view_core_->RemoveLayer(layer_); +} + +bool RenderWidgetHostViewAndroid::Animate(base::TimeTicks frame_time) { + if (!overscroll_effect_ || !HasFocus()) + return false; + return overscroll_effect_->Animate(frame_time); +} + +void RenderWidgetHostViewAndroid::UpdateAnimationSize( + const cc::CompositorFrame* frame) { + if (!overscroll_effect_) + return; + // Disable edge effects for axes on which scrolling is impossible. + const cc::CompositorFrameMetadata& metadata = frame->metadata; + gfx::SizeF ceiled_viewport_size = gfx::ToCeiledSize(metadata.viewport_size); + overscroll_effect_->set_horizontal_overscroll_enabled( + ceiled_viewport_size.width() < metadata.root_layer_size.width()); + overscroll_effect_->set_vertical_overscroll_enabled( + ceiled_viewport_size.height() < metadata.root_layer_size.height()); + overscroll_effect_->set_size(content_size_in_layer_); +} + +void RenderWidgetHostViewAndroid::ScheduleAnimationIfNecessary() { + if (!content_view_core_) + return; + if (overscroll_effect_ && overscroll_effect_->IsActive()) + content_view_core_->SetNeedsAnimate(); +} + void RenderWidgetHostViewAndroid::AcceleratedSurfacePostSubBuffer( const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params, int gpu_host_id) { @@ -875,16 +930,28 @@ SkColor RenderWidgetHostViewAndroid::GetCachedBackgroundColor() const { return cached_background_color_; } +void RenderWidgetHostViewAndroid::OnOverscrolled( + gfx::Vector2dF accumulated_overscroll, + gfx::Vector2dF current_fling_velocity) { + if (!overscroll_effect_ || !HasFocus()) + return; + overscroll_effect_->OnOverscrolled(base::TimeTicks::Now(), + accumulated_overscroll, + current_fling_velocity); + ScheduleAnimationIfNecessary(); +} + void RenderWidgetHostViewAndroid::SetContentViewCore( ContentViewCoreImpl* content_view_core) { RunAckCallbacks(); - if (content_view_core_ && is_layer_attached_) - content_view_core_->RemoveLayer(layer_); + if (are_layers_attached_) + RemoveLayers(); content_view_core_ = content_view_core; - if (content_view_core_ && is_layer_attached_) - content_view_core_->AttachLayer(layer_); + + if (are_layers_attached_) + AttachLayers(); } void RenderWidgetHostViewAndroid::RunAckCallbacks() { diff --git a/content/browser/renderer_host/render_widget_host_view_android.h b/content/browser/renderer_host/render_widget_host_view_android.h index 8a50861266..6d6215d209 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.h +++ b/content/browser/renderer_host/render_widget_host_view_android.h @@ -43,6 +43,7 @@ class WebMouseEvent; namespace content { class ContentViewCoreImpl; +class OverscrollGlow; class RenderWidgetHost; class RenderWidgetHostImpl; class SurfaceTextureTransportClient; @@ -152,6 +153,8 @@ class RenderWidgetHostViewAndroid virtual void HasTouchEventHandlers(bool need_touch_events) OVERRIDE; virtual void OnSwapCompositorFrame( scoped_ptr<cc::CompositorFrame> frame) OVERRIDE; + virtual void OnOverscrolled(gfx::Vector2dF accumulated_overscroll, + gfx::Vector2dF current_fling_velocity) OVERRIDE; virtual void ShowDisambiguationPopup(const gfx::Rect& target_rect, const SkBitmap& zoomed_bitmap) OVERRIDE; virtual SmoothScrollGesture* CreateSmoothScrollGesture( @@ -174,12 +177,12 @@ class RenderWidgetHostViewAndroid void SendMouseEvent(const WebKit::WebMouseEvent& event); void SendMouseWheelEvent(const WebKit::WebMouseWheelEvent& event); void SendGestureEvent(const WebKit::WebGestureEvent& event); - void SendVSync(base::TimeTicks frame_time); + void SendBeginFrame(base::TimeTicks frame_time); void OnProcessImeBatchStateAck(bool is_begin); void OnDidChangeBodyBackgroundColor(SkColor color); void OnStartContentIntent(const GURL& content_url); - void OnSetVSyncNotificationEnabled(bool enabled); + void OnSetNeedsBeginFrame(bool enabled); int GetNativeImeAdapter(); @@ -198,6 +201,10 @@ class RenderWidgetHostViewAndroid void RequestContentClipping(const gfx::Rect& clipping, const gfx::Size& content_size); + // Returns true when animation ticks are still needed. This avoids a separate + // round-trip for requesting follow-up animation. + bool Animate(base::TimeTicks frame_time); + private: void BuffersSwapped(const gpu::Mailbox& mailbox, const base::Closure& ack_callback); @@ -211,6 +218,12 @@ class RenderWidgetHostViewAndroid void ResetClipping(); void ClipContents(const gfx::Rect& clipping, const gfx::Size& content_size); + void AttachLayers(); + void RemoveLayers(); + + void UpdateAnimationSize(const cc::CompositorFrame* frame); + void ScheduleAnimationIfNecessary(); + // The model object. RenderWidgetHostImpl* host_; @@ -218,7 +231,7 @@ class RenderWidgetHostViewAndroid // This view may not actually be attached if this is true, but it should be // treated as such, because as soon as a ContentViewCore is set the layer // will be attached automatically. - bool is_layer_attached_; + bool are_layers_attached_; // ContentViewCoreImpl is our interface to the view system. ContentViewCoreImpl* content_view_core_; @@ -260,6 +273,9 @@ class RenderWidgetHostViewAndroid std::queue<base::Closure> ack_callbacks_; + // Used to render overscroll overlays. + scoped_ptr<OverscrollGlow> overscroll_effect_; + DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewAndroid); }; diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc index 0da585350f..c81379835e 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc @@ -632,6 +632,7 @@ RenderWidgetHostViewAura::RenderWidgetHostViewAura(RenderWidgetHost* host) text_input_type_(ui::TEXT_INPUT_TYPE_NONE), can_compose_inline_(true), has_composition_text_(false), + last_swapped_surface_scale_factor_(1.f), paint_canvas_(NULL), synthetic_move_sent_(false), accelerated_compositing_state_changed_(false), @@ -862,9 +863,12 @@ RenderWidgetHostViewAura::GetOrCreateBrowserAccessibilityManager() { return NULL; HWND hwnd = root_window->GetAcceleratedWidget(); + // The accessible_parent may be NULL at this point. The WebContents will pass + // it down to this instance (by way of the RenderViewHost and + // RenderWidgetHost) when it is known. This instance will then set it on its + // BrowserAccessibilityManager. gfx::NativeViewAccessible accessible_parent = host_->GetParentNativeViewAccessible(); - DCHECK(accessible_parent); manager = new BrowserAccessibilityManagerWin( hwnd, accessible_parent, @@ -1104,8 +1108,13 @@ void RenderWidgetHostViewAura::Destroy() { void RenderWidgetHostViewAura::SetTooltipText(const string16& tooltip_text) { tooltip_ = tooltip_text; aura::RootWindow* root_window = window_->GetRootWindow(); - if (aura::client::GetTooltipClient(root_window)) - aura::client::GetTooltipClient(root_window)->UpdateTooltip(window_); + aura::client::TooltipClient* tooltip_client = + aura::client::GetTooltipClient(root_window); + if (tooltip_client) { + tooltip_client->UpdateTooltip(window_); + // Content tooltips should be visible indefinitely. + tooltip_client->SetTooltipShownTimeout(window_, 0); + } } void RenderWidgetHostViewAura::SelectionChanged(const string16& text, @@ -1195,7 +1204,9 @@ void RenderWidgetHostViewAura::CopyFromCompositingSurfaceHelper( gfx::Rect src_subrect_in_gl = src_subrect; src_subrect_in_gl.set_y(GetViewBounds().height() - src_subrect.bottom()); - gfx::Rect src_subrect_in_pixel = ConvertRectToPixel(this, src_subrect_in_gl); + gfx::Rect src_subrect_in_pixel = + ConvertRectToPixel(current_surface_->device_scale_factor(), + src_subrect_in_gl); gl_helper->CropScaleReadbackAndCleanTexture( current_surface_->PrepareTexture(), current_surface_->size(), @@ -1215,7 +1226,7 @@ void RenderWidgetHostViewAura::CopyFromCompositingSurface( } CopyFromCompositingSurfaceHelper(src_subrect, - ConvertSizeToPixel(this, dst_size), + ConvertViewSizeToPixel(this, dst_size), callback); } @@ -1316,11 +1327,13 @@ void RenderWidgetHostViewAura::UpdateExternalTexture() { bool is_compositing_active = host_->is_accelerated_compositing_active(); if (is_compositing_active && current_surface_) { window_->SetExternalTexture(current_surface_.get()); - current_frame_size_ = ConvertSizeToDIP(this, current_surface_->size()); + current_frame_size_ = ConvertSizeToDIP( + current_surface_->device_scale_factor(), current_surface_->size()); CheckResizeLock(); } else if (is_compositing_active && current_dib_) { window_->SetExternalTexture(NULL); - current_frame_size_ = ConvertSizeToDIP(this, last_swapped_surface_size_); + current_frame_size_ = ConvertSizeToDIP(last_swapped_surface_scale_factor_, + last_swapped_surface_size_); CheckResizeLock(); } else { window_->SetExternalTexture(NULL); @@ -1331,6 +1344,7 @@ void RenderWidgetHostViewAura::UpdateExternalTexture() { bool RenderWidgetHostViewAura::SwapBuffersPrepare( const gfx::Rect& surface_rect, + float surface_scale_factor, const gfx::Rect& damage_rect, const std::string& mailbox_name, const BufferPresentedCallback& ack_callback) { @@ -1340,9 +1354,11 @@ bool RenderWidgetHostViewAura::SwapBuffersPrepare( DLOG_IF(ERROR, damage_rect != surface_rect) << "Expected full damage rect"; skipped_damage_.setEmpty(); last_swapped_surface_size_ = surface_rect.size(); + last_swapped_surface_scale_factor_ = surface_scale_factor; } - if (ShouldSkipFrame(ConvertSizeToDIP(this, surface_rect.size())) || + if (ShouldSkipFrame(ConvertSizeToDIP(surface_scale_factor, + surface_rect.size())) || mailbox_name.empty()) { skipped_damage_.op(RectToSkIRect(damage_rect), SkRegion::kUnion_Op); ack_callback.Run(true, scoped_refptr<ui::Texture>()); @@ -1351,7 +1367,7 @@ bool RenderWidgetHostViewAura::SwapBuffersPrepare( ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); current_surface_ = - factory->CreateTransportClient(current_device_scale_factor_); + factory->CreateTransportClient(surface_scale_factor); if (!current_surface_) { LOG(ERROR) << "Failed to create ImageTransport texture"; ack_callback.Run(true, scoped_refptr<ui::Texture>()); @@ -1377,7 +1393,8 @@ void RenderWidgetHostViewAura::SwapBuffersCompleted( if (frame_subscriber()->ShouldCaptureFrame(present_time, &frame, &callback)) { CopyFromCompositingSurfaceToVideoFrame( - gfx::Rect(ConvertSizeToDIP(this, current_surface_->size())), + gfx::Rect(ConvertSizeToDIP(current_surface_->device_scale_factor(), + current_surface_->size())), frame, base::Bind(callback, present_time)); } @@ -1429,7 +1446,8 @@ void RenderWidgetHostViewAura::AcceleratedSurfaceBuffersSwapped( gpu_host_id, params_in_pixel.mailbox_name); BuffersSwapped( - params_in_pixel.size, params_in_pixel.mailbox_name, ack_callback); + params_in_pixel.size, params_in_pixel.scale_factor, + params_in_pixel.mailbox_name, ack_callback); } void RenderWidgetHostViewAura::SwapDelegatedFrame( @@ -1497,6 +1515,7 @@ void RenderWidgetHostViewAura::SwapSoftwareFrame( current_dib_.reset(dib.release()); current_dib_id_ = dib_id; last_swapped_surface_size_ = frame_size; + last_swapped_surface_scale_factor_ = frame_device_scale_factor; ui::Compositor* compositor = GetCompositor(); if (!compositor) { @@ -1504,8 +1523,8 @@ void RenderWidgetHostViewAura::SwapSoftwareFrame( return; } - gfx::Size frame_size_in_dip = gfx::ToFlooredSize( - gfx::ScaleSize(frame_size, 1.0f / frame_device_scale_factor)); + gfx::Size frame_size_in_dip = + ConvertSizeToDIP(frame_device_scale_factor, frame_size); if (ShouldSkipFrame(frame_size_in_dip)) { can_lock_compositor_ = NO_PENDING_COMMIT; SendSoftwareFrameAck(last_dib_id); @@ -1519,7 +1538,8 @@ void RenderWidgetHostViewAura::SwapSoftwareFrame( CheckResizeLock(); released_front_lock_ = NULL; window_->SetExternalTexture(NULL); - window_->SchedulePaintInRect(ConvertRectToDIP(this, damage_rect)); + window_->SchedulePaintInRect( + ConvertRectToDIP(frame_device_scale_factor, damage_rect)); if (paint_observer_) paint_observer_->OnUpdateCompositorContent(); @@ -1568,17 +1588,29 @@ void RenderWidgetHostViewAura::OnSwapCompositorFrame( reinterpret_cast<const char*>(frame->gl_frame_data->mailbox.name), sizeof(frame->gl_frame_data->mailbox.name)); BuffersSwapped( - frame->gl_frame_data->size, mailbox_name, ack_callback); + frame->gl_frame_data->size, frame->metadata.device_scale_factor, + mailbox_name, ack_callback); +} + +#if defined(OS_WIN) +void RenderWidgetHostViewAura::SetParentNativeViewAccessible( + gfx::NativeViewAccessible accessible_parent) { + if (GetBrowserAccessibilityManager()) { + GetBrowserAccessibilityManager()->ToBrowserAccessibilityManagerWin() + ->set_parent_iaccessible(accessible_parent); + } } +#endif void RenderWidgetHostViewAura::BuffersSwapped( const gfx::Size& size, + float surface_scale_factor, const std::string& mailbox_name, const BufferPresentedCallback& ack_callback) { scoped_refptr<ui::Texture> texture_to_return(current_surface_); const gfx::Rect surface_rect = gfx::Rect(size); - if (!SwapBuffersPrepare( - surface_rect, surface_rect, mailbox_name, ack_callback)) { + if (!SwapBuffersPrepare(surface_rect, surface_scale_factor, surface_rect, + mailbox_name, ack_callback)) { return; } @@ -1587,7 +1619,7 @@ void RenderWidgetHostViewAura::BuffersSwapped( ui::Compositor* compositor = GetCompositor(); if (compositor) { - gfx::Size surface_size = ConvertSizeToDIP(this, size); + gfx::Size surface_size = ConvertSizeToDIP(surface_scale_factor, size); window_->SchedulePaintInRect(gfx::Rect(surface_size)); } @@ -1612,7 +1644,8 @@ void RenderWidgetHostViewAura::AcceleratedSurfacePostSubBuffer( params_in_pixel.mailbox_name); if (!SwapBuffersPrepare( - surface_rect, damage_rect, params_in_pixel.mailbox_name, ack_callback)) { + surface_rect, params_in_pixel.surface_scale_factor, damage_rect, + params_in_pixel.mailbox_name, ack_callback)) { return; } @@ -1646,12 +1679,13 @@ void RenderWidgetHostViewAura::AcceleratedSurfacePostSubBuffer( if (compositor) { // Co-ordinates come in OpenGL co-ordinate space. // We need to convert to layer space. - gfx::Rect rect_to_paint = ConvertRectToDIP(this, gfx::Rect( - params_in_pixel.x, - surface_size_in_pixel.height() - params_in_pixel.y - - params_in_pixel.height, - params_in_pixel.width, - params_in_pixel.height)); + gfx::Rect rect_to_paint = ConvertRectToDIP( + params_in_pixel.surface_scale_factor, + gfx::Rect(params_in_pixel.x, + surface_size_in_pixel.height() - params_in_pixel.y - + params_in_pixel.height, + params_in_pixel.width, + params_in_pixel.height)); // Damage may not have been DIP aligned, so inflate damage to compensate // for any round-off error. @@ -2228,7 +2262,8 @@ scoped_refptr<ui::Texture> RenderWidgetHostViewAura::CopyTexture() { return scoped_refptr<ui::Texture>( factory->CreateOwnedTexture( - current_surface_->size(), current_device_scale_factor_, texture_id)); + current_surface_->size(), + current_surface_->device_scale_factor(), texture_id)); } //////////////////////////////////////////////////////////////////////////////// diff --git a/content/browser/renderer_host/render_widget_host_view_aura.h b/content/browser/renderer_host/render_widget_host_view_aura.h index b3d3b5fae4..1b49553e84 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.h +++ b/content/browser/renderer_host/render_widget_host_view_aura.h @@ -237,6 +237,10 @@ class RenderWidgetHostViewAura virtual void UnlockMouse() OVERRIDE; virtual void OnSwapCompositorFrame( scoped_ptr<cc::CompositorFrame> frame) OVERRIDE; +#if defined(OS_WIN) + virtual void SetParentNativeViewAccessible( + gfx::NativeViewAccessible accessible_parent) OVERRIDE; +#endif // Overridden from ui::TextInputClient: virtual void SetCompositionText( @@ -333,6 +337,7 @@ class RenderWidgetHostViewAura } private: + FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest, SetCompositionText); FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest, TouchEventState); FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest, TouchEventSyncAsync); @@ -452,10 +457,12 @@ class RenderWidgetHostViewAura // The common entry point for full buffer updates from renderer // and GPU process. void BuffersSwapped(const gfx::Size& size, + float surface_scale_factor, const std::string& mailbox_name, const BufferPresentedCallback& ack_callback); bool SwapBuffersPrepare(const gfx::Rect& surface_rect, + float surface_scale_factor, const gfx::Rect& damage_rect, const std::string& mailbox_name, const BufferPresentedCallback& ack_callback); @@ -567,6 +574,7 @@ class RenderWidgetHostViewAura // Used to determine when the skipped_damage_ needs to be reset due to // size changes between front- and backbuffer. gfx::Size last_swapped_surface_size_; + float last_swapped_surface_scale_factor_; int pending_thumbnail_tasks_; 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 9ad65fcb35..8fd6f08d26 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 @@ -6,6 +6,7 @@ #include "base/basictypes.h" #include "base/message_loop.h" +#include "base/utf_string_conversions.h" #include "content/browser/renderer_host/render_widget_host_delegate.h" #include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/common/view_messages.h" @@ -173,6 +174,56 @@ TEST_F(RenderWidgetHostViewAuraTest, DestroyFullscreenOnBlur) { view_ = NULL; } +// Checks that IME-composition-event state is maintained correctly. +TEST_F(RenderWidgetHostViewAuraTest, SetCompositionText) { + view_->InitAsChild(NULL); + view_->Show(); + + ui::CompositionText composition_text; + composition_text.text = ASCIIToUTF16("|a|b"); + + // Focused segment + composition_text.underlines.push_back( + ui::CompositionUnderline(0, 3, 0xff000000, true)); + + // Non-focused segment + composition_text.underlines.push_back( + ui::CompositionUnderline(3, 4, 0xff000000, false)); + + const ui::CompositionUnderlines& underlines = composition_text.underlines; + + // Caret is at the end. (This emulates Japanese MSIME 2007 and later) + composition_text.selection = ui::Range(4); + + sink_->ClearMessages(); + view_->SetCompositionText(composition_text); + EXPECT_TRUE(view_->has_composition_text_); + { + const IPC::Message* msg = + sink_->GetFirstMessageMatching(ViewMsg_ImeSetComposition::ID); + ASSERT_TRUE(msg != NULL); + + ViewMsg_ImeSetComposition::Param params; + ViewMsg_ImeSetComposition::Read(msg, ¶ms); + // composition text + EXPECT_EQ(composition_text.text, params.a); + // underlines + ASSERT_EQ(underlines.size(), params.b.size()); + for (size_t i = 0; i < underlines.size(); ++i) { + EXPECT_EQ(underlines[i].start_offset, params.b[i].startOffset); + EXPECT_EQ(underlines[i].end_offset, params.b[i].endOffset); + EXPECT_EQ(underlines[i].color, params.b[i].color); + EXPECT_EQ(underlines[i].thick, params.b[i].thick); + } + // highlighted range + EXPECT_EQ(4, params.c) << "Should be the same to the caret pos"; + EXPECT_EQ(4, params.d) << "Should be the same to the caret pos"; + } + + view_->ImeCancelComposition(); + EXPECT_FALSE(view_->has_composition_text_); +} + // Checks that touch-event state is maintained correctly. TEST_F(RenderWidgetHostViewAuraTest, TouchEventState) { view_->InitAsChild(NULL); @@ -332,8 +383,9 @@ TEST_F(RenderWidgetHostViewAuraTest, PhysicalBackingSizeWithScale) { EXPECT_EQ(ViewMsg_Resize::ID, msg->type()); ViewMsg_Resize::Param params; ViewMsg_Resize::Read(msg, ¶ms); - EXPECT_EQ("100x100", params.a.ToString()); // dip size - EXPECT_EQ("100x100", params.b.ToString()); // backing size + EXPECT_EQ("100x100", params.a.new_size.ToString()); // dip size + EXPECT_EQ("100x100", + params.a.physical_backing_size.ToString()); // backing size } widget_host_->ResetSizeAndRepaintPendingFlags(); @@ -342,22 +394,16 @@ TEST_F(RenderWidgetHostViewAuraTest, PhysicalBackingSizeWithScale) { aura_test_helper_->test_screen()->SetDeviceScaleFactor(2.0f); EXPECT_EQ("200x200", view_->GetPhysicalBackingSize().ToString()); // Extra ScreenInfoChanged message for |parent_view_|. - EXPECT_EQ(3u, sink_->message_count()); - EXPECT_EQ(ViewMsg_ScreenInfoChanged::ID, sink_->GetMessageAt(0)->type()); - { - const IPC::Message* msg = sink_->GetMessageAt(1); - EXPECT_EQ(ViewMsg_ScreenInfoChanged::ID, msg->type()); - ViewMsg_ScreenInfoChanged::Param params; - ViewMsg_ScreenInfoChanged::Read(msg, ¶ms); - EXPECT_EQ(2.0f, params.a.deviceScaleFactor); - } + EXPECT_EQ(1u, sink_->message_count()); { - const IPC::Message* msg = sink_->GetMessageAt(2); + const IPC::Message* msg = sink_->GetMessageAt(0); EXPECT_EQ(ViewMsg_Resize::ID, msg->type()); ViewMsg_Resize::Param params; ViewMsg_Resize::Read(msg, ¶ms); - EXPECT_EQ("100x100", params.a.ToString()); // dip size - EXPECT_EQ("200x200", params.b.ToString()); // backing size + EXPECT_EQ(2.0f, params.a.screen_info.deviceScaleFactor); + EXPECT_EQ("100x100", params.a.new_size.ToString()); // dip size + EXPECT_EQ("200x200", + params.a.physical_backing_size.ToString()); // backing size } widget_host_->ResetSizeAndRepaintPendingFlags(); @@ -365,23 +411,17 @@ TEST_F(RenderWidgetHostViewAuraTest, PhysicalBackingSizeWithScale) { aura_test_helper_->test_screen()->SetDeviceScaleFactor(1.0f); // Extra ScreenInfoChanged message for |parent_view_|. - EXPECT_EQ(3u, sink_->message_count()); + EXPECT_EQ(1u, sink_->message_count()); EXPECT_EQ("100x100", view_->GetPhysicalBackingSize().ToString()); - EXPECT_EQ(ViewMsg_ScreenInfoChanged::ID, sink_->GetMessageAt(0)->type()); { - const IPC::Message* msg = sink_->GetMessageAt(1); - EXPECT_EQ(ViewMsg_ScreenInfoChanged::ID, msg->type()); - ViewMsg_ScreenInfoChanged::Param params; - ViewMsg_ScreenInfoChanged::Read(msg, ¶ms); - EXPECT_EQ(1.0f, params.a.deviceScaleFactor); - } - { - const IPC::Message* msg = sink_->GetMessageAt(2); + const IPC::Message* msg = sink_->GetMessageAt(0); EXPECT_EQ(ViewMsg_Resize::ID, msg->type()); ViewMsg_Resize::Param params; ViewMsg_Resize::Read(msg, ¶ms); - EXPECT_EQ("100x100", params.a.ToString()); // dip size - EXPECT_EQ("100x100", params.b.ToString()); // backing size + EXPECT_EQ(1.0f, params.a.screen_info.deviceScaleFactor); + EXPECT_EQ("100x100", params.a.new_size.ToString()); // dip size + EXPECT_EQ("100x100", + params.a.physical_backing_size.ToString()); // backing size } } diff --git a/content/browser/renderer_host/render_widget_host_view_base.cc b/content/browser/renderer_host/render_widget_host_view_base.cc index 43d496bc6c..c084f2ed5b 100644 --- a/content/browser/renderer_host/render_widget_host_view_base.cc +++ b/content/browser/renderer_host/render_widget_host_view_base.cc @@ -457,15 +457,10 @@ void RenderWidgetHostViewBase::UpdateScreenInfo(gfx::NativeView view) { current_device_scale_factor_ == display.device_scale_factor()) { return; } - bool device_scale_factor_changed = - current_device_scale_factor_ != display.device_scale_factor(); current_display_area_ = display.work_area(); current_device_scale_factor_ = display.device_scale_factor(); - if (impl) { + if (impl) impl->NotifyScreenInfoChanged(); - if (device_scale_factor_changed) - impl->WasResized(); - } } SmoothScrollGesture* RenderWidgetHostViewBase::CreateSmoothScrollGesture( @@ -515,4 +510,9 @@ void RenderWidgetHostViewBase::EndFrameSubscription() { render_process_host->EndFrameSubscription(impl->GetRoutingID()); } +void RenderWidgetHostViewBase::OnOverscrolled( + gfx::Vector2dF accumulated_overscroll, + gfx::Vector2dF current_fling_velocity) { +} + } // namespace content diff --git a/content/browser/renderer_host/render_widget_host_view_base.h b/content/browser/renderer_host/render_widget_host_view_base.h index 662dbaba09..fc96f7b06e 100644 --- a/content/browser/renderer_host/render_widget_host_view_base.h +++ b/content/browser/renderer_host/render_widget_host_view_base.h @@ -77,6 +77,8 @@ class CONTENT_EXPORT RenderWidgetHostViewBase virtual void EndFrameSubscription() OVERRIDE; virtual void OnSwapCompositorFrame( scoped_ptr<cc::CompositorFrame> frame) OVERRIDE {} + virtual void OnOverscrolled(gfx::Vector2dF accumulated_overscroll, + gfx::Vector2dF current_fling_velocity) OVERRIDE; void SetBrowserAccessibilityManager(BrowserAccessibilityManager* manager); diff --git a/content/browser/renderer_host/render_widget_host_view_browsertest.cc b/content/browser/renderer_host/render_widget_host_view_browsertest.cc index 45cdd4b241..33bd1cac83 100644 --- a/content/browser/renderer_host/render_widget_host_view_browsertest.cc +++ b/content/browser/renderer_host/render_widget_host_view_browsertest.cc @@ -10,112 +10,235 @@ #include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/port/browser/render_widget_host_view_frame_subscriber.h" #include "content/port/browser/render_widget_host_view_port.h" +#include "content/public/browser/compositor_util.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/web_contents.h" #include "content/public/common/content_paths.h" +#include "content/public/common/content_switches.h" #include "content/shell/shell.h" #include "content/test/content_browser_test.h" #include "content/test/content_browser_test_utils.h" #include "media/base/video_frame.h" #include "net/base/net_util.h" -#include "skia/ext/platform_canvas.h" #include "ui/compositor/compositor_setup.h" #if defined(OS_MACOSX) #include "ui/surface/io_surface_support_mac.h" #endif namespace content { +namespace { + +// Convenience macro: Short-cicuit a pass for the tests where platform support +// for forced-compositing mode (or disabled-compositing mode) is lacking. +#define SET_UP_SURFACE_OR_PASS_TEST() \ + if (!SetUpSourceSurface()) { \ + LOG(WARNING) \ + << ("Blindly passing this test: This platform does not support " \ + "forced compositing (or forced-disabled compositing) mode."); \ + return; \ + } +// Common base class for browser tests. This is subclassed twice: Once to test +// the browser in forced-compositing mode, and once to test with compositing +// mode disabled. class RenderWidgetHostViewBrowserTest : public ContentBrowserTest { public: - RenderWidgetHostViewBrowserTest() : finish_called_(false), size_(400, 300) {} + RenderWidgetHostViewBrowserTest() + : frame_size_(400, 300), + callback_invoke_count_(0), + frames_captured_(0) {} virtual void SetUpInProcessBrowserTestFixture() OVERRIDE { ASSERT_TRUE(PathService::Get(DIR_TEST_DATA, &test_dir_)); + ContentBrowserTest::SetUpInProcessBrowserTestFixture(); } - virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { - ui::DisableTestCompositor(); + // Attempts to set up the source surface. Returns false if unsupported on the + // current platform. + virtual bool SetUpSourceSurface() = 0; + + int callback_invoke_count() const { + return callback_invoke_count_; } - bool CheckAcceleratedCompositingActive() { - RenderWidgetHostImpl* impl = - RenderWidgetHostImpl::From( - shell()->web_contents()->GetRenderWidgetHostView()-> - GetRenderWidgetHost()); - return impl->is_accelerated_compositing_active(); + int frames_captured() const { + return frames_captured_; } - bool CheckCompositingSurface() { -#if defined(OS_WIN) - if (!GpuDataManagerImpl::GetInstance()->IsUsingAcceleratedSurface()) - return false; -#endif + const gfx::Size& frame_size() const { + return frame_size_; + } - RenderViewHost* const rwh = - shell()->web_contents()->GetRenderViewHost(); - RenderWidgetHostViewPort* rwhvp = - static_cast<RenderWidgetHostViewPort*>(rwh->GetView()); - bool ret = !rwhvp->GetCompositingSurface().is_null(); -#if defined(OS_MACOSX) - ret &= rwhvp->HasAcceleratedSurface(gfx::Size()); -#endif - return ret; + const base::FilePath& test_dir() const { + return test_dir_; } - bool SetupCompositingSurface() { -#if defined(OS_MACOSX) - if (!IOSurfaceSupport::Initialize()) - return false; -#endif - NavigateToURL(shell(), net::FilePathToFileURL( - test_dir_.AppendASCII("rwhv_compositing_animation.html"))); - if (!CheckAcceleratedCompositingActive()) - return false; + RenderViewHost* GetRenderViewHost() const { + RenderViewHost* const rvh = shell()->web_contents()->GetRenderViewHost(); + CHECK(rvh); + return rvh; + } - // The page is now accelerated composited but a compositing surface might - // not be available immediately so wait for it. - while (!CheckCompositingSurface()) { - base::RunLoop run_loop; - base::MessageLoop::current()->PostDelayedTask( - FROM_HERE, - run_loop.QuitClosure(), - base::TimeDelta::FromMilliseconds(10)); - run_loop.Run(); - } - return true; + RenderWidgetHostImpl* GetRenderWidgetHost() const { + RenderWidgetHostImpl* const rwh = RenderWidgetHostImpl::From( + shell()->web_contents()->GetRenderWidgetHostView()-> + GetRenderWidgetHost()); + CHECK(rwh); + return rwh; } - bool SetupNonCompositing() { - NavigateToURL(shell(), net::FilePathToFileURL( - test_dir_.AppendASCII("rwhv_compositing_static.html"))); - return !CheckCompositingSurface(); + RenderWidgetHostViewPort* GetRenderWidgetHostViewPort() const { + RenderWidgetHostViewPort* const view = + RenderWidgetHostViewPort::FromRWHV(GetRenderViewHost()->GetView()); + CHECK(view); + return view; } - void FinishCopyFromBackingStore(bool expected_result, - const base::Closure& quit_closure, - bool result, + // Callback when using CopyFromBackingStore() API. + void FinishCopyFromBackingStore(const base::Closure& quit_closure, + bool frame_captured, const SkBitmap& bitmap) { - quit_closure.Run(); - EXPECT_EQ(expected_result, result); - if (expected_result) + ++callback_invoke_count_; + if (frame_captured) { + ++frames_captured_; EXPECT_FALSE(bitmap.empty()); - finish_called_ = true; + } + if (!quit_closure.is_null()) + quit_closure.Run(); } - void FinishCopyFromCompositingSurface(bool expected_result, - const base::Closure& quit_closure, - bool result) { + // Callback when using CopyFromCompositingSurfaceToVideoFrame() API. + void FinishCopyFromCompositingSurface(const base::Closure& quit_closure, + bool frame_captured) { + ++callback_invoke_count_; + if (frame_captured) + ++frames_captured_; if (!quit_closure.is_null()) quit_closure.Run(); - EXPECT_EQ(expected_result, result); - finish_called_ = true; + } + + // Callback when using frame subscriber API. + void FrameDelivered(const scoped_refptr<base::MessageLoopProxy>& loop, + base::Closure quit_closure, + base::Time timestamp, + bool frame_captured) { + ++callback_invoke_count_; + if (frame_captured) + ++frames_captured_; + if (!quit_closure.is_null()) + loop->PostTask(FROM_HERE, quit_closure); + } + + // Copy one frame using the CopyFromBackingStore API. + void RunBasicCopyFromBackingStoreTest() { + SET_UP_SURFACE_OR_PASS_TEST(); + + // Repeatedly call CopyFromBackingStore() since, on some platforms (e.g., + // Windows), the operation will fail until the first "present" has been + // made. + int count_attempts = 0; + while (true) { + ++count_attempts; + base::RunLoop run_loop; + GetRenderViewHost()->CopyFromBackingStore( + gfx::Rect(), + frame_size(), + base::Bind( + &RenderWidgetHostViewBrowserTest::FinishCopyFromBackingStore, + base::Unretained(this), + run_loop.QuitClosure())); + run_loop.Run(); + + if (frames_captured()) + break; + else + GiveItSomeTime(); + } + + EXPECT_EQ(count_attempts, callback_invoke_count()); + EXPECT_EQ(1, frames_captured()); } protected: + // Waits until the source is available for copying. + void WaitForCopySourceReady() { + while (!GetRenderWidgetHostViewPort()->IsSurfaceAvailableForCopy()) + GiveItSomeTime(); + } + + // Run the current message loop for a short time without unwinding the current + // call stack. + static void GiveItSomeTime() { + base::RunLoop run_loop; + MessageLoop::current()->PostDelayedTask( + FROM_HERE, + run_loop.QuitClosure(), + base::TimeDelta::FromMilliseconds(10)); + run_loop.Run(); + } + + private: + const gfx::Size frame_size_; base::FilePath test_dir_; - bool finish_called_; - gfx::Size size_; + int callback_invoke_count_; + int frames_captured_; +}; + +class CompositingRenderWidgetHostViewBrowserTest + : public RenderWidgetHostViewBrowserTest { + public: + virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { + // Note: Not appending kForceCompositingMode switch here, since not all bots + // support compositing. Some bots will run with compositing on, and others + // won't. Therefore, the call to SetUpSourceSurface() later on will detect + // whether compositing mode is actually on or not. If not, the tests will + // pass blindly, logging a warning message, since we cannot test what the + // platform/implementation does not support. + RenderWidgetHostViewBrowserTest::SetUpCommandLine(command_line); + } + + virtual bool SetUpSourceSurface() OVERRIDE { + if (!IsForceCompositingModeEnabled()) + return false; // See comment in SetUpCommandLine(). +#if defined(OS_MACOSX) + CHECK(IOSurfaceSupport::Initialize()); +#endif + NavigateToURL(shell(), net::FilePathToFileURL( + test_dir().AppendASCII("rwhv_compositing_animation.html"))); +#if !defined(USE_AURA) + if (!GetRenderWidgetHost()->is_accelerated_compositing_active()) + return false; // Renderer did not turn on accelerated compositing. +#endif + + // Using accelerated compositing, but a compositing surface might not be + // available yet. So, wait for it. + WaitForCopySourceReady(); + return true; + } +}; + +class NonCompositingRenderWidgetHostViewBrowserTest + : public RenderWidgetHostViewBrowserTest { + public: + virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { + // Note: Appending the kDisableAcceleratedCompositing switch here, but there + // are some builds that only use compositing and will ignore this switch. + // Therefore, the call to SetUpSourceSurface() later on will detect whether + // compositing mode is actually off. If it's on, the tests will pass + // blindly, logging a warning message, since we cannot test what the + // platform/implementation does not support. + command_line->AppendSwitch(switches::kDisableAcceleratedCompositing); + RenderWidgetHostViewBrowserTest::SetUpCommandLine(command_line); + } + + virtual bool SetUpSourceSurface() OVERRIDE { + if (IsForceCompositingModeEnabled()) + return false; // See comment in SetUpCommandLine(). + NavigateToURL(shell(), GURL("about:blank")); + WaitForCopySourceReady(); + // Return whether the renderer left accelerated compositing turned off. + return !GetRenderWidgetHost()->is_accelerated_compositing_active(); + } }; class FakeFrameSubscriber : public RenderWidgetHostViewFrameSubscriber { @@ -146,177 +269,154 @@ class FakeFrameSubscriber : public RenderWidgetHostViewFrameSubscriber { DeliverFrameCallback callback_; }; -#if defined(OS_MACOSX) || defined(OS_WIN) +// Disable tests for Android and IOS as these platforms have incomplete +// implementation. +#if !defined(OS_ANDROID) && !defined(OS_IOS) -static void DeliverFrameFunc(const scoped_refptr<base::MessageLoopProxy>& loop, - base::Closure quit_closure, - bool* frame_captured_out, - base::Time timestamp, - bool frame_captured) { - *frame_captured_out = frame_captured; - if (!quit_closure.is_null()) - loop->PostTask(FROM_HERE, quit_closure); +// The CopyFromBackingStore() API should work on all platforms when compositing +// is enabled. +IN_PROC_BROWSER_TEST_F(CompositingRenderWidgetHostViewBrowserTest, + CopyFromBackingStore) { + RunBasicCopyFromBackingStoreTest(); } -#endif +// The CopyFromBackingStore() API should work on all platforms when compositing +// is disabled. +IN_PROC_BROWSER_TEST_F(NonCompositingRenderWidgetHostViewBrowserTest, + CopyFromBackingStore) { + RunBasicCopyFromBackingStoreTest(); +} -#if defined(OS_MACOSX) -// Tests that the callback passed to CopyFromBackingStore is always called, even -// when the RenderWidgetHost is deleting in the middle of an async copy. -IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewBrowserTest, - MacAsyncCopyFromBackingStoreCallbackTest) { - if (!SetupCompositingSurface()) { - LOG(WARNING) << "Accelerated compositing not running."; - return; - } +// Tests that the callback passed to CopyFromBackingStore is always called, +// even when the RenderWidgetHost is deleting in the middle of an async copy. +IN_PROC_BROWSER_TEST_F(CompositingRenderWidgetHostViewBrowserTest, + CopyFromBackingStore_CallbackDespiteDelete) { + SET_UP_SURFACE_OR_PASS_TEST(); base::RunLoop run_loop; - RenderViewHost* const rwh = - shell()->web_contents()->GetRenderViewHost(); - RenderWidgetHostViewPort* rwhvp = - static_cast<RenderWidgetHostViewPort*>(rwh->GetView()); - - rwh->CopyFromBackingStore( + GetRenderViewHost()->CopyFromBackingStore( gfx::Rect(), - size_, + frame_size(), base::Bind(&RenderWidgetHostViewBrowserTest::FinishCopyFromBackingStore, - base::Unretained(this), false, run_loop.QuitClosure())); - - // Delete the surface before the callback is run. This is synchronous until - // we get to the copy_timer_, so we will always end up in the destructor - // before the timer fires. - rwhvp->AcceleratedSurfaceRelease(); + base::Unretained(this), run_loop.QuitClosure())); + // Delete the surface before the callback is run. + GetRenderWidgetHostViewPort()->AcceleratedSurfaceRelease(); run_loop.Run(); - EXPECT_TRUE(finish_called_); + EXPECT_EQ(1, callback_invoke_count()); } // Tests that the callback passed to CopyFromCompositingSurfaceToVideoFrame is // always called, even when the RenderWidgetHost is deleting in the middle of // an async copy. -IN_PROC_BROWSER_TEST_F( - RenderWidgetHostViewBrowserTest, - MacAsyncCopyFromCompositingSurfaceToVideoFrameCallbackTest) { - if (!SetupCompositingSurface()) { - LOG(WARNING) << "Accelerated compositing not running."; +IN_PROC_BROWSER_TEST_F(CompositingRenderWidgetHostViewBrowserTest, + CopyFromCompositingSurface_CallbackDespiteDelete) { + SET_UP_SURFACE_OR_PASS_TEST(); + RenderWidgetHostViewPort* const view = GetRenderWidgetHostViewPort(); + if (!view->CanCopyToVideoFrame()) { + LOG(WARNING) << + ("Blindly passing this test: CopyFromCompositingSurfaceToVideoFrame() " + "not supported on this platform."); return; } base::RunLoop run_loop; - RenderViewHost* const rwh = - shell()->web_contents()->GetRenderViewHost(); - RenderWidgetHostViewPort* rwhvp = - static_cast<RenderWidgetHostViewPort*>(rwh->GetView()); - scoped_refptr<media::VideoFrame> dest = - media::VideoFrame::CreateBlackFrame(size_); - rwhvp->CopyFromCompositingSurfaceToVideoFrame( - gfx::Rect(rwhvp->GetViewBounds().size()), dest, base::Bind( + media::VideoFrame::CreateBlackFrame(frame_size()); + view->CopyFromCompositingSurfaceToVideoFrame( + gfx::Rect(view->GetViewBounds().size()), dest, base::Bind( &RenderWidgetHostViewBrowserTest::FinishCopyFromCompositingSurface, - base::Unretained(this), false, run_loop.QuitClosure())); - - // Delete the surface before the callback is run. This is synchronous until - // we get to the copy_timer_, so we will always end up in the destructor - // before the timer fires. - rwhvp->AcceleratedSurfaceRelease(); + base::Unretained(this), run_loop.QuitClosure())); + // Delete the surface before the callback is run. + view->AcceleratedSurfaceRelease(); run_loop.Run(); - ASSERT_TRUE(finish_called_); + EXPECT_EQ(1, callback_invoke_count()); } -#endif -#if (defined(OS_WIN) && !defined(USE_AURA)) || defined(OS_MACOSX) -IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewBrowserTest, +// With compositing turned off, no platforms should support the +// CopyFromCompositingSurfaceToVideoFrame() API. +IN_PROC_BROWSER_TEST_F(NonCompositingRenderWidgetHostViewBrowserTest, + CopyFromCompositingSurfaceToVideoFrameCallbackTest) { + SET_UP_SURFACE_OR_PASS_TEST(); + EXPECT_FALSE(GetRenderWidgetHostViewPort()->CanCopyToVideoFrame()); +} + +// Test basic frame subscription functionality. We subscribe, and then run +// until at least one DeliverFrameCallback has been invoked. +IN_PROC_BROWSER_TEST_F(CompositingRenderWidgetHostViewBrowserTest, FrameSubscriberTest) { - if (!SetupCompositingSurface()) { - LOG(WARNING) << "Accelerated compositing not running."; + SET_UP_SURFACE_OR_PASS_TEST(); + RenderWidgetHostViewPort* const view = GetRenderWidgetHostViewPort(); + if (!view->CanSubscribeFrame()) { + LOG(WARNING) << ("Blindly passing this test: Frame subscription not " + "supported on this platform."); return; } - - base::RunLoop run_loop; - RenderWidgetHostViewPort* view = RenderWidgetHostViewPort::FromRWHV( - shell()->web_contents()->GetRenderViewHost()->GetView()); - ASSERT_TRUE(view); - - if (!view->CanSubscribeFrame()) { - LOG(WARNING) << "Frame subscription no supported on this platform."; +#if defined(USE_AURA) + if (ui::IsTestCompositorEnabled()) { + LOG(WARNING) << ("Blindly passing this test: Aura test compositor doesn't " + "support frame subscription."); + // TODO(miu): Aura test compositor should support frame subscription for + // testing. http://crbug.com/240572 return; } +#endif - bool frame_captured = false; + base::RunLoop run_loop; scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber( - new FakeFrameSubscriber(base::Bind(&DeliverFrameFunc, - base::MessageLoopProxy::current(), - run_loop.QuitClosure(), - &frame_captured))); + new FakeFrameSubscriber( + base::Bind(&RenderWidgetHostViewBrowserTest::FrameDelivered, + base::Unretained(this), + base::MessageLoopProxy::current(), + run_loop.QuitClosure()))); view->BeginFrameSubscription(subscriber.Pass()); run_loop.Run(); view->EndFrameSubscription(); - EXPECT_TRUE(frame_captured); -} - -// Test copying from backing store when page is non-accelerated-composited. -// Flaky. http://crbug.com/224351 -#if defined(OS_MACOSX) || defined(OS_WIN) -#define MAYBE_CopyFromBackingStore DISABLED_CopyFromBackingStore -#else -#define MAYBE_CopyFromBackingStore CopyFromBackingStore -#endif -IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewBrowserTest, - MAYBE_CopyFromBackingStore) { - SetupNonCompositing(); - base::RunLoop run_loop; - - shell()->web_contents()->GetRenderViewHost()->CopyFromBackingStore( - gfx::Rect(), - size_, - base::Bind(&RenderWidgetHostViewBrowserTest::FinishCopyFromBackingStore, - base::Unretained(this), true, run_loop.QuitClosure())); - run_loop.Run(); - EXPECT_TRUE(finish_called_); + EXPECT_LE(1, callback_invoke_count()); + EXPECT_LE(1, frames_captured()); } -#endif -#if defined(OS_MACOSX) // Test that we can copy twice from an accelerated composited page. -// This test is only running on Mac because this is the only platform that -// we can reliably detect that accelerated surface is in use. -IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewBrowserTest, CopyTwice) { - if (!SetupCompositingSurface()) { - LOG(WARNING) << "Accelerated compositing not running."; +IN_PROC_BROWSER_TEST_F(CompositingRenderWidgetHostViewBrowserTest, CopyTwice) { + SET_UP_SURFACE_OR_PASS_TEST(); + RenderWidgetHostViewPort* const view = GetRenderWidgetHostViewPort(); + if (!view->CanCopyToVideoFrame()) { + LOG(WARNING) << ("Blindly passing this test: " + "CopyFromCompositingSurfaceToVideoFrame() not supported " + "on this platform."); return; } base::RunLoop run_loop; - RenderViewHost* const rwh = - shell()->web_contents()->GetRenderViewHost(); - RenderWidgetHostViewPort* rwhvp = - static_cast<RenderWidgetHostViewPort*>(rwh->GetView()); - scoped_refptr<media::VideoFrame> dest = - media::VideoFrame::CreateBlackFrame(size_); - - bool first_frame_captured = false; - bool second_frame_captured = false; - rwhvp->CopyFromCompositingSurfaceToVideoFrame( - gfx::Rect(rwhvp->GetViewBounds().size()), dest, - base::Bind(&DeliverFrameFunc, + scoped_refptr<media::VideoFrame> first_output = + media::VideoFrame::CreateBlackFrame(frame_size()); + ASSERT_TRUE(first_output); + scoped_refptr<media::VideoFrame> second_output = + media::VideoFrame::CreateBlackFrame(frame_size()); + ASSERT_TRUE(second_output); + view->CopyFromCompositingSurfaceToVideoFrame( + gfx::Rect(view->GetViewBounds().size()), first_output, + base::Bind(&RenderWidgetHostViewBrowserTest::FrameDelivered, + base::Unretained(this), base::MessageLoopProxy::current(), base::Closure(), - &first_frame_captured, base::Time::Now())); - rwhvp->CopyFromCompositingSurfaceToVideoFrame( - gfx::Rect(rwhvp->GetViewBounds().size()), dest, - base::Bind(&DeliverFrameFunc, + view->CopyFromCompositingSurfaceToVideoFrame( + gfx::Rect(view->GetViewBounds().size()), second_output, + base::Bind(&RenderWidgetHostViewBrowserTest::FrameDelivered, + base::Unretained(this), base::MessageLoopProxy::current(), run_loop.QuitClosure(), - &second_frame_captured, base::Time::Now())); run_loop.Run(); - EXPECT_TRUE(first_frame_captured); - EXPECT_TRUE(second_frame_captured); + EXPECT_EQ(2, callback_invoke_count()); + EXPECT_EQ(2, frames_captured()); } -#endif +#endif // !defined(OS_ANDROID) && !defined(OS_IOS) + +} // namespace } // namespace content diff --git a/content/browser/renderer_host/render_widget_host_view_guest.cc b/content/browser/renderer_host/render_widget_host_view_guest.cc index 6f02367111..a706d25db0 100644 --- a/content/browser/renderer_host/render_widget_host_view_guest.cc +++ b/content/browser/renderer_host/render_widget_host_view_guest.cc @@ -81,7 +81,8 @@ void RenderWidgetHostViewGuest::SetSize(const gfx::Size& size) { } gfx::Rect RenderWidgetHostViewGuest::GetBoundsInRootWindow() { - return gfx::Rect(size_); + // We do not have any root window specific parts in this view. + return GetViewBounds(); } gfx::GLSurfaceHandle RenderWidgetHostViewGuest::GetCompositingSurface() { @@ -125,7 +126,12 @@ bool RenderWidgetHostViewGuest::IsShowing() { } gfx::Rect RenderWidgetHostViewGuest::GetViewBounds() const { - return gfx::Rect(size_); + gfx::Rect embedder_bounds = static_cast<RenderWidgetHostViewPort*>( + guest_->GetEmbedderRenderWidgetHostView())->GetViewBounds(); + gfx::Rect shifted_rect = guest_->ToGuestRect(embedder_bounds); + shifted_rect.set_width(size_.width()); + shifted_rect.set_height(size_.height()); + return shifted_rect; } void RenderWidgetHostViewGuest::RenderViewGone(base::TerminationStatus status, @@ -433,6 +439,12 @@ void RenderWidgetHostViewGuest::WillWmDestroy() { } #endif +#if defined(OS_WIN) && defined(USE_AURA) +void RenderWidgetHostViewGuest::SetParentNativeViewAccessible( + gfx::NativeViewAccessible accessible_parent) { +} +#endif + void RenderWidgetHostViewGuest::DestroyGuestView() { host_ = NULL; base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); diff --git a/content/browser/renderer_host/render_widget_host_view_guest.h b/content/browser/renderer_host/render_widget_host_view_guest.h index b1c2816d3d..84900b72ec 100644 --- a/content/browser/renderer_host/render_widget_host_view_guest.h +++ b/content/browser/renderer_host/render_widget_host_view_guest.h @@ -175,6 +175,11 @@ class CONTENT_EXPORT RenderWidgetHostViewGuest virtual void WillWmDestroy() OVERRIDE; #endif // defined(OS_WIN) && !defined(USE_AURA) +#if defined(OS_WIN) && defined(USE_AURA) + virtual void SetParentNativeViewAccessible( + gfx::NativeViewAccessible accessible_parent) OVERRIDE; +#endif + // Overridden from ui::GestureEventHelper. virtual bool DispatchLongPressGestureEvent(ui::GestureEvent* event) OVERRIDE; virtual bool DispatchCancelTouchEvent(ui::TouchEvent* event) OVERRIDE; diff --git a/content/browser/renderer_host/render_widget_host_view_mac.h b/content/browser/renderer_host/render_widget_host_view_mac.h index 4a9ce80114..3b98f255b8 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac.h +++ b/content/browser/renderer_host/render_widget_host_view_mac.h @@ -325,7 +325,8 @@ class RenderWidgetHostViewMac : public RenderWidgetHostViewBase, // Call setNeedsDisplay on the cocoa_view_. The IOSurface will be drawn during // the next drawRect. Return true if the Ack should be sent, false if it // should be deferred until drawRect. - bool CompositorSwapBuffers(uint64 surface_handle, const gfx::Size& size); + bool CompositorSwapBuffers( + uint64 surface_handle, const gfx::Size& size, float scale_factor); // Ack pending SwapBuffers requests, if any, to unblock the GPU process. Has // no effect if there are no pending requests. void AckPendingSwapBuffers(); diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm index e99db477e7..200c1aa335 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac.mm +++ b/content/browser/renderer_host/render_widget_host_view_mac.mm @@ -33,7 +33,6 @@ #include "content/common/edit_command.h" #include "content/common/gpu/gpu_messages.h" #include "content/common/input_messages.h" -#include "content/common/plugin_messages.h" #include "content/common/view_messages.h" #include "content/port/browser/render_widget_host_view_frame_subscriber.h" #include "content/public/browser/browser_thread.h" @@ -553,6 +552,8 @@ void RenderWidgetHostViewMac::WasHidden() { // disableScreenUpdatesUntilFlush prevents the transparent flash by avoiding // screen updates until the next tab draws. [[cocoa_view_ window] disableScreenUpdatesUntilFlush]; + + web_contents_switch_paint_time_ = base::TimeTicks(); } void RenderWidgetHostViewMac::SetSize(const gfx::Size& size) { @@ -942,7 +943,6 @@ void RenderWidgetHostViewMac::CopyFromCompositingSurface( scoped_callback_runner.Release(); compositing_iosurface_->CopyTo(GetScaledOpenGLPixelRect(src_subrect), - ScaleFactor(cocoa_view_), dst_pixel_size, callback); } @@ -974,7 +974,6 @@ void RenderWidgetHostViewMac::CopyFromCompositingSurfaceToVideoFrame( scoped_callback_runner.Release(); compositing_iosurface_->CopyToVideoFrame( GetScaledOpenGLPixelRect(src_subrect), - ScaleFactor(cocoa_view_), target, callback); } @@ -1045,7 +1044,8 @@ void RenderWidgetHostViewMac::PluginImeCompositionCompleted( } bool RenderWidgetHostViewMac::CompositorSwapBuffers(uint64 surface_handle, - const gfx::Size& size) { + const gfx::Size& size, + float scale_factor) { if (is_hidden_) return true; @@ -1059,9 +1059,10 @@ bool RenderWidgetHostViewMac::CompositorSwapBuffers(uint64 surface_handle, RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback callback; if (frame_subscriber_->ShouldCaptureFrame(present_time, &frame, &callback)) { - compositing_iosurface_->SetIOSurface(surface_handle, size); + compositing_iosurface_->SetIOSurface( + surface_handle, size, scale_factor); compositing_iosurface_->CopyToVideoFrame( - gfx::Rect(size), ScaleFactor(cocoa_view_), frame, + gfx::Rect(size), frame, base::Bind(callback, present_time)); return true; } @@ -1101,7 +1102,7 @@ bool RenderWidgetHostViewMac::CompositorSwapBuffers(uint64 surface_handle, if (!compositing_iosurface_) return true; - compositing_iosurface_->SetIOSurface(surface_handle, size); + compositing_iosurface_->SetIOSurface(surface_handle, size, scale_factor); GotAcceleratedFrame(); @@ -1311,7 +1312,9 @@ void RenderWidgetHostViewMac::AcceleratedSurfaceBuffersSwapped( pending_swap_buffers_acks_.push_back(std::make_pair(params.route_id, gpu_host_id)); - if (CompositorSwapBuffers(params.surface_handle, params.size)) + if (CompositorSwapBuffers(params.surface_handle, + params.size, + params.scale_factor)) AckPendingSwapBuffers(); } @@ -1325,7 +1328,9 @@ void RenderWidgetHostViewMac::AcceleratedSurfacePostSubBuffer( pending_swap_buffers_acks_.push_back(std::make_pair(params.route_id, gpu_host_id)); - if (CompositorSwapBuffers(params.surface_handle, params.surface_size)) + if (CompositorSwapBuffers(params.surface_handle, + params.surface_size, + params.surface_scale_factor)) AckPendingSwapBuffers(); } @@ -1340,20 +1345,11 @@ void RenderWidgetHostViewMac::AcceleratedSurfaceRelease() { bool RenderWidgetHostViewMac::HasAcceleratedSurface( const gfx::Size& desired_size) { - // Update device scale factor for the IOSurface before checking if there - // is a match. When initially created, the IOSurface is unaware of its - // scale factor, which can result in compatible IOSurfaces not being used - // http://crbug.com/237293 - if (compositing_iosurface_.get() && - compositing_iosurface_->HasIOSurface()) { - compositing_iosurface_->SetDeviceScaleFactor(ScaleFactor(cocoa_view_)); - } - return last_frame_was_accelerated_ && compositing_iosurface_.get() && compositing_iosurface_->HasIOSurface() && (desired_size.IsEmpty() || - compositing_iosurface_->io_surface_size() == desired_size); + compositing_iosurface_->dip_io_surface_size() == desired_size); } void RenderWidgetHostViewMac::AboutToWaitForBackingStoreMsg() { diff --git a/content/browser/renderer_host/render_widget_host_view_win.cc b/content/browser/renderer_host/render_widget_host_view_win.cc index 000e53227f..a68d8f6f82 100644 --- a/content/browser/renderer_host/render_widget_host_view_win.cc +++ b/content/browser/renderer_host/render_widget_host_view_win.cc @@ -6,12 +6,12 @@ #include <dwmapi.h> #include <InputScope.h> +#include <wtsapi32.h> +#pragma comment(lib, "wtsapi32.lib") #include <algorithm> #include <map> #include <stack> -#include <wtsapi32.h> -#pragma comment(lib, "wtsapi32.lib") #include "base/bind.h" #include "base/bind_helpers.h" @@ -40,7 +40,6 @@ #include "content/browser/renderer_host/ui_events_helper.h" #include "content/common/accessibility_messages.h" #include "content/common/gpu/gpu_messages.h" -#include "content/common/plugin_messages.h" #include "content/common/view_messages.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/child_process_data.h" @@ -52,11 +51,11 @@ #include "content/public/common/page_zoom.h" #include "content/public/common/process_type.h" #include "skia/ext/skia_utils_win.h" -#include "third_party/skia/include/core/SkRegion.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebCompositionUnderline.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" #include "third_party/WebKit/Source/WebKit/chromium/public/win/WebInputEventFactory.h" #include "third_party/WebKit/Source/WebKit/chromium/public/win/WebScreenInfoFactory.h" +#include "third_party/skia/include/core/SkRegion.h" #include "ui/base/events/event.h" #include "ui/base/events/event_utils.h" #include "ui/base/ime/composition_text.h" @@ -489,6 +488,8 @@ void RenderWidgetHostViewWin::WasHidden() { if (GetBrowserAccessibilityManager()) GetBrowserAccessibilityManager()->WasHidden(); + + web_contents_switch_paint_time_ = base::TimeTicks(); } void RenderWidgetHostViewWin::SetSize(const gfx::Size& size) { diff --git a/content/browser/renderer_host/socket_stream_dispatcher_host.cc b/content/browser/renderer_host/socket_stream_dispatcher_host.cc index 3d0157be56..fbbc790ab3 100644 --- a/content/browser/renderer_host/socket_stream_dispatcher_host.cc +++ b/content/browser/renderer_host/socket_stream_dispatcher_host.cc @@ -202,6 +202,9 @@ void SocketStreamDispatcherHost::OnConnect(int render_view_id, LOG(ERROR) << "socket_id=" << socket_id << " already registered."; return; } + + // Note that the SocketStreamHost is responsible for checking that |url| + // is valid. SocketStreamHost* socket_stream_host = new SocketStreamHost(this, render_view_id, socket_id); hosts_.AddWithID(socket_stream_host, socket_id); diff --git a/content/browser/renderer_host/surface_texture_transport_client_android.cc b/content/browser/renderer_host/surface_texture_transport_client_android.cc index 03056c0935..94b199e20a 100644 --- a/content/browser/renderer_host/surface_texture_transport_client_android.cc +++ b/content/browser/renderer_host/surface_texture_transport_client_android.cc @@ -13,6 +13,8 @@ #include "content/browser/renderer_host/image_transport_factory_android.h" #include "content/public/browser/browser_thread.h" #include "third_party/WebKit/Source/Platform/chromium/public/WebGraphicsContext3D.h" +#include "third_party/khronos/GLES2/gl2.h" +#include "third_party/khronos/GLES2/gl2ext.h" #include "ui/gl/android/surface_texture_bridge.h" namespace content { @@ -99,7 +101,9 @@ scoped_refptr<media::VideoFrame> SurfaceTextureTransportClient:: ImageTransportFactoryAndroid::GetInstance()->GetContext3D(); context->makeContextCurrent(); texture_id_ = context->createTexture(); - surface_texture_->AttachToGLContext(texture_id_); + context->bindTexture(GL_TEXTURE_EXTERNAL_OES, texture_id_); + context->flush(); + surface_texture_->AttachToGLContext(); } if (!video_frame_) { const gfx::Size size = video_layer_->bounds(); diff --git a/content/browser/renderer_host/test_render_view_host.cc b/content/browser/renderer_host/test_render_view_host.cc index a84f4dcd36..be2fab97bb 100644 --- a/content/browser/renderer_host/test_render_view_host.cc +++ b/content/browser/renderer_host/test_render_view_host.cc @@ -13,12 +13,12 @@ #include "content/public/browser/navigation_controller.h" #include "content/public/browser/storage_partition.h" #include "content/public/common/content_client.h" +#include "content/public/common/page_state.h" #include "content/public/common/password_form.h" #include "content/test/test_web_contents.h" #include "media/base/video_frame.h" #include "ui/gfx/rect.h" #include "webkit/dom_storage/dom_storage_types.h" -#include "webkit/glue/glue_serialize.h" #include "webkit/glue/webpreferences.h" namespace content { @@ -58,7 +58,7 @@ void InitNavigateParams(ViewHostMsg_FrameNavigate_Params* params, params->gesture = NavigationGestureUser; params->was_within_same_page = false; params->is_post = false; - params->content_state = webkit_glue::CreateHistoryStateForURL(GURL(url)); + params->page_state = PageState::CreateFromURL(url); } TestRenderWidgetHostView::TestRenderWidgetHostView(RenderWidgetHost* rwh) @@ -229,6 +229,12 @@ bool TestRenderWidgetHostView::LockMouse() { void TestRenderWidgetHostView::UnlockMouse() { } +#if defined(OS_WIN) && defined(USE_AURA) +void TestRenderWidgetHostView::SetParentNativeViewAccessible( + gfx::NativeViewAccessible accessible_parent) { +} +#endif + TestRenderViewHost::TestRenderViewHost( SiteInstance* instance, RenderViewHostDelegate* delegate, @@ -337,20 +343,11 @@ void TestRenderViewHost::SendNavigateWithParameters( params.history_list_was_cleared = simulate_history_list_was_cleared_; params.original_request_url = original_request_url; - WebKit::WebHTTPBody http_body; - http_body.initialize(); - - WebKit::WebHistoryItem history_item; - history_item.initialize(); - history_item.setURLString(WebKit::WebString::fromUTF8(url.spec())); - if (file_path_for_history_item) { - const char char_data[] = "data"; - http_body.appendData(WebKit::WebData(char_data, arraysize(char_data)-1)); - http_body.appendFile(WebKit::WebString::fromUTF8( - file_path_for_history_item->MaybeAsASCII())); - history_item.setHTTPBody(http_body); - } - params.content_state = webkit_glue::HistoryItemToString(history_item); + params.page_state = PageState::CreateForTesting( + url, + false, + file_path_for_history_item ? "data" : NULL, + file_path_for_history_item); ViewHostMsg_FrameNavigate msg(1, params); OnNavigate(msg); @@ -388,17 +385,11 @@ void TestRenderViewHost::TestOnStartDragging( void TestRenderViewHost::TestOnUpdateStateWithFile( int process_id, const base::FilePath& file_path) { - WebKit::WebHTTPBody http_body; - http_body.initialize(); - const char char_data[] = "data"; - http_body.appendData(WebKit::WebData(char_data, arraysize(char_data)-1)); - http_body.appendFile(WebKit::WebString::fromUTF8(file_path.MaybeAsASCII())); - - WebKit::WebHistoryItem history_item; - history_item.initialize(); - history_item.setURLString("http://www.google.com"); - history_item.setHTTPBody(http_body); - OnUpdateState(process_id, webkit_glue::HistoryItemToString(history_item)); + OnUpdateState(process_id, + PageState::CreateForTesting(GURL("http://www.google.com"), + false, + "data", + &file_path)); } void TestRenderViewHost::set_simulate_fetch_via_proxy(bool proxy) { diff --git a/content/browser/renderer_host/test_render_view_host.h b/content/browser/renderer_host/test_render_view_host.h index 68634d4ac6..9fb3cfc577 100644 --- a/content/browser/renderer_host/test_render_view_host.h +++ b/content/browser/renderer_host/test_render_view_host.h @@ -164,6 +164,10 @@ class TestRenderWidgetHostView : public RenderWidgetHostViewBase { #endif virtual bool LockMouse() OVERRIDE; virtual void UnlockMouse() OVERRIDE; +#if defined(OS_WIN) && defined(USE_AURA) + virtual void SetParentNativeViewAccessible( + gfx::NativeViewAccessible accessible_parent) OVERRIDE; +#endif bool is_showing() const { return is_showing_; } diff --git a/content/browser/renderer_host/touchpad_tap_suppression_controller.h b/content/browser/renderer_host/touchpad_tap_suppression_controller.h index 76e1fc1810..e2ce4c956c 100644 --- a/content/browser/renderer_host/touchpad_tap_suppression_controller.h +++ b/content/browser/renderer_host/touchpad_tap_suppression_controller.h @@ -6,7 +6,6 @@ #define CONTENT_BROWSER_RENDERER_HOST_TOUCHPAD_TAP_SUPPRESSION_CONTROLLER_H_ #include "base/memory/scoped_ptr.h" -#include "cc/debug/latency_info.h" #include "content/browser/renderer_host/event_with_latency_info.h" #include "content/browser/renderer_host/tap_suppression_controller_client.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" diff --git a/content/browser/resources/media/data_series.js b/content/browser/resources/media/data_series.js index 3dfad4e280..8947492dbf 100644 --- a/content/browser/resources/media/data_series.js +++ b/content/browser/resources/media/data_series.js @@ -31,6 +31,24 @@ var TimelineDataSeries = (function() { TimelineDataSeries.prototype = { /** + * @override + */ + toJSON: function() { + if (this.dataPoints_.length < 1) + return {}; + + var values = []; + for (var i = 0; i < this.dataPoints_.length; ++i) { + values.push(this.dataPoints_[i].value); + } + return { + startTime: this.dataPoints_[0].time, + endTime: this.dataPoints_[this.dataPoints_.length - 1].time, + values: JSON.stringify(values), + }; + }, + + /** * Adds a DataPoint to |this| with the specified time and value. * DataPoints are assumed to be received in chronological order. */ diff --git a/content/browser/resources/media/dump_creator.js b/content/browser/resources/media/dump_creator.js index 3770e4884b..55eecd1013 100644 --- a/content/browser/resources/media/dump_creator.js +++ b/content/browser/resources/media/dump_creator.js @@ -5,9 +5,8 @@ /** * Provides the UI to start and stop RTP recording, forwards the start/stop - * commands to Chrome, and updates the UI based on dump updates. - * - * @param {Element} containerElement The parent element of the dump creation UI. + * commands to Chrome, and updates the UI based on dump updates. Also provides + * creating a file containing all PeerConnection updates and stats. */ var DumpCreator = (function() { /** @@ -54,20 +53,40 @@ var DumpCreator = (function() { summary.textContent = 'Create Dump'; var content = document.createElement('pre'); this.root_.appendChild(content); - content.innerHTML = '<button></button> Status: <span></span>'; + + content.innerHTML = '<button></button> Status: <span></span>' + + '<div><form><button>' + + 'Download the PeerConnection updates and stats data' + + '</button></form></div>'; content.getElementsByTagName('button')[0].addEventListener( - 'click', this.onToggled_.bind(this)); + 'click', this.onRtpToggled_.bind(this)); + content.getElementsByTagName('button')[1].addEventListener( + 'click', this.onDownloadData_.bind(this)); this.updateDisplay_(); } DumpCreator.prototype = { /** - * Handles the event of toggling the dump recording state. + * Downloads the PeerConnection updates and stats data as a file. + * + * @private + */ + onDownloadData_: function() { + var textBlob = + new Blob([JSON.stringify(peerConnectionDataStore, null, ' ')], + {type: 'octet/stream'}); + var URL = window.webkitURL.createObjectURL(textBlob); + this.root_.getElementsByTagName('form')[0].action = URL; + // The default action of the button will submit the form. + }, + + /** + * Handles the event of toggling the rtp recording state. * * @private */ - onToggled_: function() { + onRtpToggled_: function() { if (this.recording_) { this.recording_ = false; this.status_ = this.StatusStrings_.NOT_STARTED; diff --git a/content/browser/resources/media/peer_connection_update_table.js b/content/browser/resources/media/peer_connection_update_table.js index facbefa707..0f4cc0cde9 100644 --- a/content/browser/resources/media/peer_connection_update_table.js +++ b/content/browser/resources/media/peer_connection_update_table.js @@ -63,7 +63,7 @@ var PeerConnectionUpdateTable = (function() { * @const * @private */ - this.UPDATE_LOG_TABLE_CLASS_ = 'update-log-table'; + this.UPDATE_LOG_TABLE_CLASS = 'update-log-table'; } PeerConnectionUpdateTable.prototype = { @@ -113,7 +113,7 @@ var PeerConnectionUpdateTable = (function() { peerConnectionElement.appendChild(tableContainer); tableElement = document.createElement('table'); - tableElement.className = this.UPDATE_LOG_TABLE_CLASS_; + tableElement.className = this.UPDATE_LOG_TABLE_CLASS; tableElement.id = tableId; tableElement.border = 1; tableContainer.appendChild(tableElement); diff --git a/content/browser/resources/media/stats_graph_helper.js b/content/browser/resources/media/stats_graph_helper.js index 7c89554490..c8fa4e633a 100644 --- a/content/browser/resources/media/stats_graph_helper.js +++ b/content/browser/resources/media/stats_graph_helper.js @@ -11,7 +11,6 @@ // Each group has an expand/collapse button and is collapsed initially. // -<include src="data_series.js"/> <include src="timeline_graph_view.js"/> var STATS_GRAPH_CONTAINER_HEADING_CLASS = 'stats-graph-container-heading'; @@ -88,7 +87,6 @@ var statsNameBlackList = { }; var graphViews = {}; -var dataSeries = {}; // Adds the stats report |report| to the timeline graph for the given // |peerConnectionElement|. @@ -107,8 +105,7 @@ function drawSingleReport(peerConnectionElement, report) { if (isNaN(rawValue)) continue; - var rawDataSeriesId = - peerConnectionElement.id + '-' + reportId + '-' + rawLabel; + var rawDataSeriesId = reportId + '-' + rawLabel; var finalDataSeriesId = rawDataSeriesId; var finalLabel = rawLabel; @@ -116,21 +113,25 @@ function drawSingleReport(peerConnectionElement, report) { // We need to convert the value if dataConversionConfig[rawLabel] exists. if (dataConversionConfig[rawLabel]) { // Updates the original dataSeries before the conversion. - addDataSeriesPoint(rawDataSeriesId, stats.timestamp, + addDataSeriesPoint(peerConnectionElement, + rawDataSeriesId, stats.timestamp, rawLabel, rawValue); // Convert to another value to draw on graph, using the original // dataSeries as input. finalValue = dataConversionConfig[rawLabel].convertFunction( - dataSeries[rawDataSeriesId]); + peerConnectionDataStore[peerConnectionElement.id].getDataSeries( + rawDataSeriesId)); finalLabel = dataConversionConfig[rawLabel].convertedName; - finalDataSeriesId = - peerConnectionElement.id + '-' + reportId + '-' + finalLabel; + finalDataSeriesId = reportId + '-' + finalLabel; } // Updates the final dataSeries to draw. - addDataSeriesPoint( - finalDataSeriesId, stats.timestamp, finalLabel, finalValue); + addDataSeriesPoint(peerConnectionElement, + finalDataSeriesId, + stats.timestamp, + finalLabel, + finalValue); // Updates the graph. var graphType = bweCompoundGraphConfig[finalLabel] ? @@ -147,24 +148,31 @@ function drawSingleReport(peerConnectionElement, report) { } // Adds the new dataSeries to the graphView. We have to do it here to cover // both the simple and compound graph cases. - if (!graphViews[graphViewId].hasDataSeries(dataSeries[finalDataSeriesId])) - graphViews[graphViewId].addDataSeries(dataSeries[finalDataSeriesId]); - + var dataSeries = + peerConnectionDataStore[peerConnectionElement.id].getDataSeries( + finalDataSeriesId); + if (!graphViews[graphViewId].hasDataSeries(dataSeries)) + graphViews[graphViewId].addDataSeries(dataSeries); graphViews[graphViewId].updateEndDate(); } } // Makes sure the TimelineDataSeries with id |dataSeriesId| is created, // and adds the new data point to it. -function addDataSeriesPoint(dataSeriesId, time, label, value) { - if (!dataSeries[dataSeriesId]) { - dataSeries[dataSeriesId] = new TimelineDataSeries(); +function addDataSeriesPoint( + peerConnectionElement, dataSeriesId, time, label, value) { + var dataSeries = + peerConnectionDataStore[peerConnectionElement.id].getDataSeries( + dataSeriesId); + if (!dataSeries) { + dataSeries = new TimelineDataSeries(); + peerConnectionDataStore[peerConnectionElement.id].setDataSeries( + dataSeriesId, dataSeries); if (bweCompoundGraphConfig[label]) { - dataSeries[dataSeriesId].setColor( - bweCompoundGraphConfig[label].color); + dataSeries.setColor(bweCompoundGraphConfig[label].color); } } - dataSeries[dataSeriesId].addPoint(time, value); + dataSeries.addPoint(time, value); } // Ensures a div container to hold all stats graphs for one track is created as @@ -202,8 +210,8 @@ function createStatsGraphView( var topContainer = ensureStatsGraphTopContainer(peerConnectionElement, report); - var graphViewId = peerConnectionElement.id + '-' + - report.type + '-' + report.id + '-' + statsName; + var graphViewId = + peerConnectionElement.id + '-' + report.id + '-' + statsName; var divId = graphViewId + '-div'; var canvasId = graphViewId + '-canvas'; var container = document.createElement("div"); @@ -214,8 +222,7 @@ function createStatsGraphView( '<div id=' + divId + '><canvas id=' + canvasId + '></canvas></div>'; if (statsName == 'bweCompound') { container.insertBefore( - createBweCompoundLegend( - peerConnectionElement, report.type + '-' + report.id), + createBweCompoundLegend(peerConnectionElement, report.id), $(divId)); } return new TimelineGraphView(divId, canvasId); @@ -223,18 +230,20 @@ function createStatsGraphView( // Creates the legend section for the bweCompound graph. // Returns the legend element. -function createBweCompoundLegend(peerConnectionElement, reportName) { +function createBweCompoundLegend(peerConnectionElement, reportId) { var legend = document.createElement('div'); for (var prop in bweCompoundGraphConfig) { var div = document.createElement('div'); legend.appendChild(div); div.innerHTML = '<input type=checkbox checked></input>' + prop; div.style.color = bweCompoundGraphConfig[prop].color; - div.dataSeriesId = peerConnectionElement.id + '-' + reportName + '-' + prop; + div.dataSeriesId = reportId + '-' + prop; div.graphViewId = - peerConnectionElement.id + '-' + reportName + '-bweCompound'; + peerConnectionElement.id + '-' + reportId + '-bweCompound'; div.firstChild.addEventListener('click', function(event) { - var target = dataSeries[event.target.parentNode.dataSeriesId]; + var target = + peerConnectionDataStore[peerConnectionElement.id].getDataSeries( + event.target.parentNode.dataSeriesId); target.show(event.target.checked); graphViews[event.target.parentNode.graphViewId].repaint(); }); diff --git a/content/browser/resources/media/webrtc_internals.js b/content/browser/resources/media/webrtc_internals.js index 6dd1bb11f3..fd2d34a3fa 100644 --- a/content/browser/resources/media/webrtc_internals.js +++ b/content/browser/resources/media/webrtc_internals.js @@ -8,17 +8,85 @@ var ssrcInfoManager = null; var peerConnectionUpdateTable = null; var statsTable = null; var dumpCreator = null; +/** A map from peer connection id to the PeerConnectionRecord. */ +var peerConnectionDataStore = {}; + +/** A simple class to store the updates and stats data for a peer connection. */ +var PeerConnectionRecord = (function() { + /** @constructor */ + function PeerConnectionRecord() { + /** @private */ + this.record_ = { + constraints: {}, + servers: [], + stats: {}, + updateLog: [], + url: '', + }; + }; + + PeerConnectionRecord.prototype = { + /** @override */ + toJSON: function() { + return this.record_; + }, + + /** + * Adds the initilization info of the peer connection. + * @param {string} url The URL of the web page owning the peer connection. + * @param {Array} servers STUN servers used by the peer connection. + * @param {!Object} constraints Media constraints. + */ + initialize: function(url, servers, constraints) { + this.record_.url = url; + this.record_.servers = servers; + this.record_.constraints = constraints; + }, + + /** + * @param {string} dataSeriesId The TimelineDataSeries identifier. + * @return {!TimelineDataSeries} + */ + getDataSeries: function(dataSeriesId) { + return this.record_.stats[dataSeriesId]; + }, + + /** + * @param {string} dataSeriesId The TimelineDataSeries identifier. + * @param {!TimelineDataSeries} dataSeries The TimelineDataSeries to set to. + */ + setDataSeries: function(dataSeriesId, dataSeries) { + this.record_.stats[dataSeriesId] = dataSeries; + }, + + /** + * @param {string} type The type of the update. + * @param {string} value The value of the update. + */ + addUpdate: function(type, value) { + this.record_.updateLog.push({ + time: (new Date()).toLocaleString(), + type: type, + value: value, + }); + }, + }; + + return PeerConnectionRecord; +})(); // The maximum number of data points bufferred for each stats. Old data points // will be shifted out when the buffer is full. var MAX_STATS_DATA_POINT_BUFFER_SIZE = 1000; +<include src="data_series.js"/> <include src="ssrc_info_manager.js"/> <include src="stats_graph_helper.js"/> <include src="stats_table.js"/> <include src="peer_connection_update_table.js"/> <include src="dump_creator.js"/> + function initialize() { peerConnectionsListElem = $('peer-connections-list'); dumpCreator = new DumpCreator(peerConnectionsListElem); @@ -63,8 +131,21 @@ function extractSsrcInfo(data) { /** - * Browser message handlers. + * Helper for adding a peer connection update. + * + * @param {Element} peerConnectionElement + * @param {!PeerConnectionUpdateEntry} update The peer connection update data. */ +function addPeerConnectionUpdate(peerConnectionElement, update) { + peerConnectionUpdateTable.addPeerConnectionUpdate(peerConnectionElement, + update); + extractSsrcInfo(update); + peerConnectionDataStore[peerConnectionElement.id].addUpdate( + update.type, update.value); +} + + +/** Browser message handlers. */ /** @@ -75,8 +156,10 @@ function extractSsrcInfo(data) { */ function removePeerConnection(data) { var element = $(getPeerConnectionId(data)); - if (element) + if (element) { + delete peerConnectionDataStore[element.id]; peerConnectionsListElem.removeChild(element); + } } @@ -87,11 +170,19 @@ function removePeerConnection(data) { * constraints of a peer connection. */ function addPeerConnection(data) { - var peerConnectionElement = $(getPeerConnectionId(data)); + var id = getPeerConnectionId(data); + + if (!peerConnectionDataStore[id]) { + peerConnectionDataStore[id] = new PeerConnectionRecord(); + } + peerConnectionDataStore[id].initialize( + data.url, data.servers, data.constraints); + + var peerConnectionElement = $(id); if (!peerConnectionElement) { peerConnectionElement = document.createElement('li'); peerConnectionsListElem.appendChild(peerConnectionElement); - peerConnectionElement.id = getPeerConnectionId(data); + peerConnectionElement.id = id; } peerConnectionElement.innerHTML = '<h3>PeerConnection ' + peerConnectionElement.id + '</h3>' + @@ -106,6 +197,7 @@ function addPeerConnection(data) { else e.target.parentElement.className = ''; }); + return peerConnectionElement; } @@ -117,9 +209,7 @@ function addPeerConnection(data) { */ function updatePeerConnection(data) { var peerConnectionElement = $(getPeerConnectionId(data)); - peerConnectionUpdateTable.addPeerConnectionUpdate( - peerConnectionElement, data); - extractSsrcInfo(data); + addPeerConnectionUpdate(peerConnectionElement, data); } @@ -136,9 +226,7 @@ function updateAllPeerConnections(data) { var log = data[i].log; for (var j = 0; j < log.length; ++j) { - peerConnectionUpdateTable.addPeerConnectionUpdate( - peerConnection, log[j]); - extractSsrcInfo(log[j]); + addPeerConnectionUpdate(peerConnection, log[j]); } } } diff --git a/content/browser/session_history_browsertest.cc b/content/browser/session_history_browsertest.cc index 5de632a402..d8a24efe19 100644 --- a/content/browser/session_history_browsertest.cc +++ b/content/browser/session_history_browsertest.cc @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/stringprintf.h" #include "base/string_util.h" #include "base/utf_string_conversions.h" #include "content/public/browser/navigation_controller.h" @@ -14,18 +15,44 @@ #include "content/shell/shell.h" #include "content/test/content_browser_test.h" #include "content/test/content_browser_test_utils.h" -#include "net/test/spawned_test_server/spawned_test_server.h" +#include "net/test/embedded_test_server/embedded_test_server.h" +#include "net/test/embedded_test_server/http_response.h" +#include "net/test/embedded_test_server/http_request.h" #include "testing/gtest/include/gtest/gtest.h" namespace content { +namespace { + +// Handles |request| by serving a response with title set to request contents. +scoped_ptr<net::test_server::HttpResponse> HandleEchoTitleRequest( + const std::string& echotitle_path, + const net::test_server::HttpRequest& request) { + if (!StartsWithASCII(request.relative_url, echotitle_path, true)) + return scoped_ptr<net::test_server::HttpResponse>(NULL); + + scoped_ptr<net::test_server::BasicHttpResponse> http_response( + new net::test_server::BasicHttpResponse); + http_response->set_code(net::test_server::SUCCESS); + http_response->set_content( + base::StringPrintf( + "<html><head><title>%s</title></head></html>", + request.content.c_str())); + return http_response.PassAs<net::test_server::HttpResponse>(); +} + +} // namespace + class SessionHistoryTest : public ContentBrowserTest { protected: SessionHistoryTest() {} virtual void SetUpOnMainThread() OVERRIDE { - ASSERT_TRUE(test_server()->Start()); - NavigateToURL(shell(), GURL(chrome::kAboutBlankURL)); + ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); + embedded_test_server()->RegisterRequestHandler( + base::Bind(&HandleEchoTitleRequest, "/echotitle")); + + NavigateToURL(shell(), GURL(kAboutBlankURL)); } // Simulate clicking a link. Only works on the frames.html testserver page. @@ -66,7 +93,8 @@ class SessionHistoryTest : public ContentBrowserTest { } GURL GetURL(const std::string file) { - return test_server()->GetURL(std::string("files/session_history/") + file); + return embedded_test_server()->GetURL( + std::string("/session_history/") + file); } void NavigateAndCheckTitle(const char* filename, @@ -176,7 +204,7 @@ IN_PROC_BROWSER_TEST_F(SessionHistoryTest, FrameBackForward) { GoBack(); EXPECT_EQ("about:blank", GetTabTitle()); - EXPECT_EQ(GURL(chrome::kAboutBlankURL), GetTabURL()); + EXPECT_EQ(GURL(kAboutBlankURL), GetTabURL()); GoForward(); EXPECT_EQ("bot1", GetTabTitle()); @@ -297,6 +325,9 @@ IN_PROC_BROWSER_TEST_F(SessionHistoryTest, CrossFrameFormBackForward) { // navigations. Bug 730379. // If this flakes use http://crbug.com/61619. IN_PROC_BROWSER_TEST_F(SessionHistoryTest, FragmentBackForward) { + embedded_test_server()->RegisterRequestHandler( + base::Bind(&HandleEchoTitleRequest, "/echotitle")); + ASSERT_FALSE(CanGoBack()); GURL fragment(GetURL("fragment.html")); diff --git a/content/browser/site_instance_impl_unittest.cc b/content/browser/site_instance_impl_unittest.cc index d98591c19e..ac0ca0bd7e 100644 --- a/content/browser/site_instance_impl_unittest.cc +++ b/content/browser/site_instance_impl_unittest.cc @@ -20,6 +20,7 @@ #include "content/public/common/content_constants.h" #include "content/public/common/content_switches.h" #include "content/public/common/url_constants.h" +#include "content/public/common/url_utils.h" #include "content/public/test/mock_render_process_host.h" #include "content/public/test/test_browser_context.h" #include "content/public/test/test_browser_thread.h" diff --git a/content/browser/speech/proto/speech_proto.target.darwin-arm.mk b/content/browser/speech/proto/speech_proto.target.darwin-arm.mk index 9e7cf389e9..7d9a93e1c8 100644 --- a/content/browser/speech/proto/speech_proto.target.darwin-arm.mk +++ b/content/browser/speech/proto/speech_proto.target.darwin-arm.mk @@ -17,14 +17,14 @@ GYP_TARGET_DEPENDENCIES := \ ### Generated for rule "content_browser_speech_proto_speech_proto_gyp_speech_proto_target_genproto": # "{'inputs': ['../../../../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'msvs_cygwin_shell': '0', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['google_streaming_api.proto'], 'action': ['python', '../../../../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', '.', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)', 'process_outputs_as_sources': '1'}": $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_local_path := $(LOCAL_PATH) -$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir) -$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir) +$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir)) +$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir)) $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH)) $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: $(LOCAL_PATH)/content/browser/speech/proto/google_streaming_api.proto $(LOCAL_PATH)/tools/protoc_wrapper/protoc_wrapper.py $(gyp_shared_intermediate_dir)/protoc $(GYP_TARGET_DEPENDENCIES) mkdir -p $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto $(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto; cd $(gyp_local_path)/content/browser/speech/proto; python ../../../../tools/protoc_wrapper/protoc_wrapper.py --include "" --protobuf "$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/google_streaming_api.pb.h" --proto-in-dir . --proto-in-file "google_streaming_api$(suffix $<)" "--use-system-protobuf=0" -- "$(gyp_shared_intermediate_dir)/protoc" --cpp_out "$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto" --python_out "$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto" -$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/google_streaming_api.pb.cc: $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py -$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/google_streaming_api.pb.h: $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py +$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/google_streaming_api.pb.cc: $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py ; +$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/google_streaming_api.pb.h: $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py ; .PHONY: content_browser_speech_proto_speech_proto_gyp_rule_trigger content_browser_speech_proto_speech_proto_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py @@ -97,6 +97,7 @@ MY_DEFS := \ '-DNO_TCMALLOC' \ '-DDISABLE_NACL' \ '-DCHROMIUM_BUILD' \ + '-DENABLE_DOUBLE_RESOURCE_LOAD_TIMING' \ '-DUSE_LIBJPEG_TURBO=1' \ '-DUSE_PROPRIETARY_CODECS' \ '-DENABLE_GPU=1' \ @@ -123,9 +124,9 @@ LOCAL_C_INCLUDES := \ $(LOCAL_PATH) \ $(LOCAL_PATH)/third_party/protobuf \ $(LOCAL_PATH)/third_party/protobuf/src \ - $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \ - $(GYP_ABS_ANDROID_TOP_DIR)/bionic \ - $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport + $(PWD)/frameworks/wilhelm/include \ + $(PWD)/bionic \ + $(PWD)/external/stlport/stlport LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES) diff --git a/content/browser/speech/proto/speech_proto.target.darwin-x86.mk b/content/browser/speech/proto/speech_proto.target.darwin-x86.mk index 991fe36e69..311d79ac4a 100644 --- a/content/browser/speech/proto/speech_proto.target.darwin-x86.mk +++ b/content/browser/speech/proto/speech_proto.target.darwin-x86.mk @@ -17,14 +17,14 @@ GYP_TARGET_DEPENDENCIES := \ ### Generated for rule "content_browser_speech_proto_speech_proto_gyp_speech_proto_target_genproto": # "{'inputs': ['../../../../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'msvs_cygwin_shell': '0', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['google_streaming_api.proto'], 'action': ['python', '../../../../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', '.', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)', 'process_outputs_as_sources': '1'}": $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_local_path := $(LOCAL_PATH) -$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir) -$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir) +$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir)) +$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir)) $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH)) $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: $(LOCAL_PATH)/content/browser/speech/proto/google_streaming_api.proto $(LOCAL_PATH)/tools/protoc_wrapper/protoc_wrapper.py $(gyp_shared_intermediate_dir)/protoc $(GYP_TARGET_DEPENDENCIES) mkdir -p $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto $(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto; cd $(gyp_local_path)/content/browser/speech/proto; python ../../../../tools/protoc_wrapper/protoc_wrapper.py --include "" --protobuf "$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/google_streaming_api.pb.h" --proto-in-dir . --proto-in-file "google_streaming_api$(suffix $<)" "--use-system-protobuf=0" -- "$(gyp_shared_intermediate_dir)/protoc" --cpp_out "$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto" --python_out "$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto" -$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/google_streaming_api.pb.cc: $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py -$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/google_streaming_api.pb.h: $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py +$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/google_streaming_api.pb.cc: $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py ; +$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/google_streaming_api.pb.h: $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py ; .PHONY: content_browser_speech_proto_speech_proto_gyp_rule_trigger content_browser_speech_proto_speech_proto_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py @@ -99,6 +99,7 @@ MY_DEFS := \ '-DNO_TCMALLOC' \ '-DDISABLE_NACL' \ '-DCHROMIUM_BUILD' \ + '-DENABLE_DOUBLE_RESOURCE_LOAD_TIMING' \ '-DUSE_LIBJPEG_TURBO=1' \ '-DUSE_PROPRIETARY_CODECS' \ '-DENABLE_GPU=1' \ @@ -125,9 +126,9 @@ LOCAL_C_INCLUDES := \ $(LOCAL_PATH) \ $(LOCAL_PATH)/third_party/protobuf \ $(LOCAL_PATH)/third_party/protobuf/src \ - $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \ - $(GYP_ABS_ANDROID_TOP_DIR)/bionic \ - $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport + $(PWD)/frameworks/wilhelm/include \ + $(PWD)/bionic \ + $(PWD)/external/stlport/stlport LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES) diff --git a/content/browser/speech/proto/speech_proto.target.linux-arm.mk b/content/browser/speech/proto/speech_proto.target.linux-arm.mk index 9e7cf389e9..7d9a93e1c8 100644 --- a/content/browser/speech/proto/speech_proto.target.linux-arm.mk +++ b/content/browser/speech/proto/speech_proto.target.linux-arm.mk @@ -17,14 +17,14 @@ GYP_TARGET_DEPENDENCIES := \ ### Generated for rule "content_browser_speech_proto_speech_proto_gyp_speech_proto_target_genproto": # "{'inputs': ['../../../../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'msvs_cygwin_shell': '0', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['google_streaming_api.proto'], 'action': ['python', '../../../../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', '.', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)', 'process_outputs_as_sources': '1'}": $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_local_path := $(LOCAL_PATH) -$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir) -$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir) +$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir)) +$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir)) $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH)) $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: $(LOCAL_PATH)/content/browser/speech/proto/google_streaming_api.proto $(LOCAL_PATH)/tools/protoc_wrapper/protoc_wrapper.py $(gyp_shared_intermediate_dir)/protoc $(GYP_TARGET_DEPENDENCIES) mkdir -p $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto $(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto; cd $(gyp_local_path)/content/browser/speech/proto; python ../../../../tools/protoc_wrapper/protoc_wrapper.py --include "" --protobuf "$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/google_streaming_api.pb.h" --proto-in-dir . --proto-in-file "google_streaming_api$(suffix $<)" "--use-system-protobuf=0" -- "$(gyp_shared_intermediate_dir)/protoc" --cpp_out "$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto" --python_out "$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto" -$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/google_streaming_api.pb.cc: $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py -$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/google_streaming_api.pb.h: $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py +$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/google_streaming_api.pb.cc: $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py ; +$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/google_streaming_api.pb.h: $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py ; .PHONY: content_browser_speech_proto_speech_proto_gyp_rule_trigger content_browser_speech_proto_speech_proto_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py @@ -97,6 +97,7 @@ MY_DEFS := \ '-DNO_TCMALLOC' \ '-DDISABLE_NACL' \ '-DCHROMIUM_BUILD' \ + '-DENABLE_DOUBLE_RESOURCE_LOAD_TIMING' \ '-DUSE_LIBJPEG_TURBO=1' \ '-DUSE_PROPRIETARY_CODECS' \ '-DENABLE_GPU=1' \ @@ -123,9 +124,9 @@ LOCAL_C_INCLUDES := \ $(LOCAL_PATH) \ $(LOCAL_PATH)/third_party/protobuf \ $(LOCAL_PATH)/third_party/protobuf/src \ - $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \ - $(GYP_ABS_ANDROID_TOP_DIR)/bionic \ - $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport + $(PWD)/frameworks/wilhelm/include \ + $(PWD)/bionic \ + $(PWD)/external/stlport/stlport LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES) diff --git a/content/browser/speech/proto/speech_proto.target.linux-x86.mk b/content/browser/speech/proto/speech_proto.target.linux-x86.mk index 991fe36e69..311d79ac4a 100644 --- a/content/browser/speech/proto/speech_proto.target.linux-x86.mk +++ b/content/browser/speech/proto/speech_proto.target.linux-x86.mk @@ -17,14 +17,14 @@ GYP_TARGET_DEPENDENCIES := \ ### Generated for rule "content_browser_speech_proto_speech_proto_gyp_speech_proto_target_genproto": # "{'inputs': ['../../../../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'msvs_cygwin_shell': '0', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['google_streaming_api.proto'], 'action': ['python', '../../../../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', '.', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)', 'process_outputs_as_sources': '1'}": $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_local_path := $(LOCAL_PATH) -$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir) -$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir) +$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir)) +$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir)) $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH)) $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: $(LOCAL_PATH)/content/browser/speech/proto/google_streaming_api.proto $(LOCAL_PATH)/tools/protoc_wrapper/protoc_wrapper.py $(gyp_shared_intermediate_dir)/protoc $(GYP_TARGET_DEPENDENCIES) mkdir -p $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto $(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto; cd $(gyp_local_path)/content/browser/speech/proto; python ../../../../tools/protoc_wrapper/protoc_wrapper.py --include "" --protobuf "$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/google_streaming_api.pb.h" --proto-in-dir . --proto-in-file "google_streaming_api$(suffix $<)" "--use-system-protobuf=0" -- "$(gyp_shared_intermediate_dir)/protoc" --cpp_out "$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto" --python_out "$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto" -$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/google_streaming_api.pb.cc: $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py -$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/google_streaming_api.pb.h: $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py +$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/google_streaming_api.pb.cc: $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py ; +$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/google_streaming_api.pb.h: $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py ; .PHONY: content_browser_speech_proto_speech_proto_gyp_rule_trigger content_browser_speech_proto_speech_proto_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py @@ -99,6 +99,7 @@ MY_DEFS := \ '-DNO_TCMALLOC' \ '-DDISABLE_NACL' \ '-DCHROMIUM_BUILD' \ + '-DENABLE_DOUBLE_RESOURCE_LOAD_TIMING' \ '-DUSE_LIBJPEG_TURBO=1' \ '-DUSE_PROPRIETARY_CODECS' \ '-DENABLE_GPU=1' \ @@ -125,9 +126,9 @@ LOCAL_C_INCLUDES := \ $(LOCAL_PATH) \ $(LOCAL_PATH)/third_party/protobuf \ $(LOCAL_PATH)/third_party/protobuf/src \ - $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \ - $(GYP_ABS_ANDROID_TOP_DIR)/bionic \ - $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport + $(PWD)/frameworks/wilhelm/include \ + $(PWD)/bionic \ + $(PWD)/external/stlport/stlport LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES) diff --git a/content/browser/speech/speech_recognition_manager_impl.cc b/content/browser/speech/speech_recognition_manager_impl.cc index ea49579e07..f1dca141ea 100644 --- a/content/browser/speech/speech_recognition_manager_impl.cc +++ b/content/browser/speech/speech_recognition_manager_impl.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -10,7 +10,7 @@ #include "content/browser/speech/google_one_shot_remote_engine.h" #include "content/browser/speech/google_streaming_remote_engine.h" #include "content/browser/speech/speech_recognition_engine.h" -#include "content/browser/speech/speech_recognizer.h" +#include "content/browser/speech/speech_recognizer_impl.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/content_browser_client.h" #include "content/public/browser/resource_context.h" @@ -92,9 +92,10 @@ int SpeechRecognitionManagerImpl::CreateSession( SpeechRecognitionEngineConfig remote_engine_config; remote_engine_config.language = config.language; remote_engine_config.grammars = config.grammars; - remote_engine_config.audio_sample_rate = SpeechRecognizer::kAudioSampleRate; + remote_engine_config.audio_sample_rate = + SpeechRecognizerImpl::kAudioSampleRate; remote_engine_config.audio_num_bits_per_sample = - SpeechRecognizer::kNumBitsPerAudioSample; + SpeechRecognizerImpl::kNumBitsPerAudioSample; remote_engine_config.filter_profanities = config.filter_profanities; remote_engine_config.continuous = config.continuous; remote_engine_config.interim_results = config.interim_results; @@ -117,7 +118,7 @@ int SpeechRecognitionManagerImpl::CreateSession( // The legacy api cannot use continuous mode. DCHECK(!config.is_legacy_api || !config.continuous); - session.recognizer = new SpeechRecognizer( + session.recognizer = new SpeechRecognizerImpl( this, session_id, !config.continuous, diff --git a/content/browser/speech/speech_recognizer.h b/content/browser/speech/speech_recognizer.h index 12da90564e..bb8fd9760e 100644 --- a/content/browser/speech/speech_recognizer.h +++ b/content/browser/speech/speech_recognizer.h @@ -1,155 +1,37 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CONTENT_BROWSER_SPEECH_SPEECH_RECOGNIZER_H_ #define CONTENT_BROWSER_SPEECH_SPEECH_RECOGNIZER_H_ -#include "base/basictypes.h" #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" -#include "content/browser/speech/endpointer/endpointer.h" -#include "content/browser/speech/speech_recognition_engine.h" -#include "content/public/common/speech_recognition_error.h" -#include "content/public/common/speech_recognition_result.h" -#include "media/audio/audio_input_controller.h" -#include "net/url_request/url_request_context_getter.h" - -namespace media { -class AudioManager; -} namespace content { class SpeechRecognitionEventListener; -// Handles speech recognition for a session (identified by |session_id|), taking -// care of audio capture, silence detection/endpointer and interaction with the -// SpeechRecognitionEngine. +// Handles speech recognition for a session (identified by |session_id|). class CONTENT_EXPORT SpeechRecognizer - : public base::RefCountedThreadSafe<SpeechRecognizer>, - public media::AudioInputController::EventHandler, - public NON_EXPORTED_BASE(SpeechRecognitionEngineDelegate) { + : public base::RefCountedThreadSafe<SpeechRecognizer> { public: - static const int kAudioSampleRate; - static const media::ChannelLayout kChannelLayout; - static const int kNumBitsPerAudioSample; - static const int kNoSpeechTimeoutMs; - static const int kEndpointerEstimationTimeMs; - - static void SetAudioManagerForTests(media::AudioManager* audio_manager); - SpeechRecognizer(SpeechRecognitionEventListener* listener, - int session_id, - bool is_single_shot, - SpeechRecognitionEngine* engine); + SpeechRecognizer(SpeechRecognitionEventListener* listener, int session_id) + : listener_(listener), session_id_(session_id) {} - void StartRecognition(); - void AbortRecognition(); - void StopAudioCapture(); - bool IsActive() const; - bool IsCapturingAudio() const; - const SpeechRecognitionEngine& recognition_engine() const; + virtual void StartRecognition() = 0; + virtual void AbortRecognition() = 0; + virtual void StopAudioCapture() = 0; + virtual bool IsActive() const = 0; + virtual bool IsCapturingAudio() const = 0; - private: + protected: friend class base::RefCountedThreadSafe<SpeechRecognizer>; - friend class SpeechRecognizerTest; - - enum FSMState { - STATE_IDLE = 0, - STATE_STARTING, - STATE_ESTIMATING_ENVIRONMENT, - STATE_WAITING_FOR_SPEECH, - STATE_RECOGNIZING, - STATE_WAITING_FINAL_RESULT, - STATE_MAX_VALUE = STATE_WAITING_FINAL_RESULT - }; - - enum FSMEvent { - EVENT_ABORT = 0, - EVENT_START, - EVENT_STOP_CAPTURE, - EVENT_AUDIO_DATA, - EVENT_ENGINE_RESULT, - EVENT_ENGINE_ERROR, - EVENT_AUDIO_ERROR, - EVENT_MAX_VALUE = EVENT_AUDIO_ERROR - }; - - struct FSMEventArgs { - explicit FSMEventArgs(FSMEvent event_value); - ~FSMEventArgs(); - - FSMEvent event; - scoped_refptr<AudioChunk> audio_data; - SpeechRecognitionResults engine_results; - SpeechRecognitionError engine_error; - }; - - virtual ~SpeechRecognizer(); - - // Entry point for pushing any new external event into the recognizer FSM. - void DispatchEvent(const FSMEventArgs& event_args); - - // Defines the behavior of the recognizer FSM, selecting the appropriate - // transition according to the current state and event. - FSMState ExecuteTransitionAndGetNextState(const FSMEventArgs& args); - - // Process a new audio chunk in the audio pipeline (endpointer, vumeter, etc). - void ProcessAudioPipeline(const AudioChunk& raw_audio); - - // The methods below handle transitions of the recognizer FSM. - FSMState StartRecording(const FSMEventArgs& event_args); - FSMState StartRecognitionEngine(const FSMEventArgs& event_args); - FSMState WaitEnvironmentEstimationCompletion(const FSMEventArgs& event_args); - FSMState DetectUserSpeechOrTimeout(const FSMEventArgs& event_args); - FSMState StopCaptureAndWaitForResult(const FSMEventArgs& event_args); - FSMState ProcessIntermediateResult(const FSMEventArgs& event_args); - FSMState ProcessFinalResult(const FSMEventArgs& event_args); - FSMState AbortSilently(const FSMEventArgs& event_args); - FSMState AbortWithError(const FSMEventArgs& event_args); - FSMState Abort(const SpeechRecognitionError& error); - FSMState DetectEndOfSpeech(const FSMEventArgs& event_args); - FSMState DoNothing(const FSMEventArgs& event_args) const; - FSMState NotFeasible(const FSMEventArgs& event_args); - - // Returns the time span of captured audio samples since the start of capture. - int GetElapsedTimeMs() const; - - // Calculates the input volume to be displayed in the UI, triggering the - // OnAudioLevelsChange event accordingly. - void UpdateSignalAndNoiseLevels(const float& rms, bool clip_detected); - - void CloseAudioControllerAsynchronously(); - - // Callback called on IO thread by audio_controller->Close(). - void OnAudioClosed(media::AudioInputController*); - - // AudioInputController::EventHandler methods. - virtual void OnCreated(media::AudioInputController* controller) OVERRIDE {} - virtual void OnRecording(media::AudioInputController* controller) OVERRIDE {} - virtual void OnError(media::AudioInputController* controller) OVERRIDE; - virtual void OnData(media::AudioInputController* controller, - const uint8* data, uint32 size) OVERRIDE; - - // SpeechRecognitionEngineDelegate methods. - virtual void OnSpeechRecognitionEngineResults( - const SpeechRecognitionResults& results) OVERRIDE; - virtual void OnSpeechRecognitionEngineError( - const SpeechRecognitionError& error) OVERRIDE; - static media::AudioManager* audio_manager_for_tests_; + virtual ~SpeechRecognizer() {} SpeechRecognitionEventListener* listener_; - scoped_ptr<SpeechRecognitionEngine> recognition_engine_; - Endpointer endpointer_; - scoped_refptr<media::AudioInputController> audio_controller_; int session_id_; - int num_samples_recorded_; - float audio_level_; - bool is_dispatching_event_; - bool is_single_shot_; - FSMState state_; DISALLOW_COPY_AND_ASSIGN(SpeechRecognizer); }; diff --git a/content/browser/speech/speech_recognizer.cc b/content/browser/speech/speech_recognizer_impl.cc index 62c1b35f3e..d207ba4857 100644 --- a/content/browser/speech/speech_recognizer.cc +++ b/content/browser/speech/speech_recognizer_impl.cc @@ -1,8 +1,8 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "content/browser/speech/speech_recognizer.h" +#include "content/browser/speech/speech_recognizer_impl.h" #include "base/basictypes.h" #include "base/bind.h" @@ -12,9 +12,6 @@ #include "content/browser/speech/google_one_shot_remote_engine.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/speech_recognition_event_listener.h" -#include "content/public/common/speech_recognition_error.h" -#include "content/public/common/speech_recognition_grammar.h" -#include "content/public/common/speech_recognition_result.h" #include "net/url_request/url_request_context_getter.h" using media::AudioInputController; @@ -62,26 +59,25 @@ void KeepAudioControllerRefcountedForDtor(scoped_refptr<AudioInputController>) { } // namespace -const int SpeechRecognizer::kAudioSampleRate = 16000; -const ChannelLayout SpeechRecognizer::kChannelLayout = +const int SpeechRecognizerImpl::kAudioSampleRate = 16000; +const ChannelLayout SpeechRecognizerImpl::kChannelLayout = media::CHANNEL_LAYOUT_MONO; -const int SpeechRecognizer::kNumBitsPerAudioSample = 16; -const int SpeechRecognizer::kNoSpeechTimeoutMs = 8000; -const int SpeechRecognizer::kEndpointerEstimationTimeMs = 300; -media::AudioManager* SpeechRecognizer::audio_manager_for_tests_ = NULL; +const int SpeechRecognizerImpl::kNumBitsPerAudioSample = 16; +const int SpeechRecognizerImpl::kNoSpeechTimeoutMs = 8000; +const int SpeechRecognizerImpl::kEndpointerEstimationTimeMs = 300; +media::AudioManager* SpeechRecognizerImpl::audio_manager_for_tests_ = NULL; -COMPILE_ASSERT(SpeechRecognizer::kNumBitsPerAudioSample % 8 == 0, +COMPILE_ASSERT(SpeechRecognizerImpl::kNumBitsPerAudioSample % 8 == 0, kNumBitsPerAudioSample_must_be_a_multiple_of_8); -SpeechRecognizer::SpeechRecognizer( +SpeechRecognizerImpl::SpeechRecognizerImpl( SpeechRecognitionEventListener* listener, int session_id, bool is_single_shot, SpeechRecognitionEngine* engine) - : listener_(listener), + : SpeechRecognizer(listener, session_id), recognition_engine_(engine), endpointer_(kAudioSampleRate), - session_id_(session_id), is_dispatching_event_(false), is_single_shot_(is_single_shot), state_(STATE_IDLE) { @@ -114,32 +110,32 @@ SpeechRecognizer::SpeechRecognizer( // of causality between events and avoid interleaved event processing due to // synchronous callbacks. -void SpeechRecognizer::StartRecognition() { +void SpeechRecognizerImpl::StartRecognition() { BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, - base::Bind(&SpeechRecognizer::DispatchEvent, + base::Bind(&SpeechRecognizerImpl::DispatchEvent, this, FSMEventArgs(EVENT_START))); } -void SpeechRecognizer::AbortRecognition() { +void SpeechRecognizerImpl::AbortRecognition() { BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, - base::Bind(&SpeechRecognizer::DispatchEvent, + base::Bind(&SpeechRecognizerImpl::DispatchEvent, this, FSMEventArgs(EVENT_ABORT))); } -void SpeechRecognizer::StopAudioCapture() { +void SpeechRecognizerImpl::StopAudioCapture() { BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, - base::Bind(&SpeechRecognizer::DispatchEvent, + base::Bind(&SpeechRecognizerImpl::DispatchEvent, this, FSMEventArgs(EVENT_STOP_CAPTURE))); } -bool SpeechRecognizer::IsActive() const { +bool SpeechRecognizerImpl::IsActive() const { // Checking the FSM state from another thread (thus, while the FSM is // potentially concurrently evolving) is meaningless. DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); return state_ != STATE_IDLE; } -bool SpeechRecognizer::IsCapturingAudio() const { +bool SpeechRecognizerImpl::IsCapturingAudio() const { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); // See IsActive(). const bool is_capturing_audio = state_ >= STATE_STARTING && state_ <= STATE_RECOGNIZING; @@ -149,11 +145,11 @@ bool SpeechRecognizer::IsCapturingAudio() const { } const SpeechRecognitionEngine& -SpeechRecognizer::recognition_engine() const { +SpeechRecognizerImpl::recognition_engine() const { return *(recognition_engine_.get()); } -SpeechRecognizer::~SpeechRecognizer() { +SpeechRecognizerImpl::~SpeechRecognizerImpl() { endpointer_.EndSession(); if (audio_controller_) { audio_controller_->Close(base::Bind(&KeepAudioControllerRefcountedForDtor, @@ -162,14 +158,14 @@ SpeechRecognizer::~SpeechRecognizer() { } // Invoked in the audio thread. -void SpeechRecognizer::OnError(AudioInputController* controller) { +void SpeechRecognizerImpl::OnError(AudioInputController* controller) { FSMEventArgs event_args(EVENT_AUDIO_ERROR); BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, - base::Bind(&SpeechRecognizer::DispatchEvent, + base::Bind(&SpeechRecognizerImpl::DispatchEvent, this, event_args)); } -void SpeechRecognizer::OnData(AudioInputController* controller, +void SpeechRecognizerImpl::OnData(AudioInputController* controller, const uint8* data, uint32 size) { if (size == 0) // This could happen when audio capture stops and is normal. return; @@ -178,27 +174,27 @@ void SpeechRecognizer::OnData(AudioInputController* controller, event_args.audio_data = new AudioChunk(data, static_cast<size_t>(size), kNumBitsPerAudioSample / 8); BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, - base::Bind(&SpeechRecognizer::DispatchEvent, + base::Bind(&SpeechRecognizerImpl::DispatchEvent, this, event_args)); } -void SpeechRecognizer::OnAudioClosed(AudioInputController*) {} +void SpeechRecognizerImpl::OnAudioClosed(AudioInputController*) {} -void SpeechRecognizer::OnSpeechRecognitionEngineResults( +void SpeechRecognizerImpl::OnSpeechRecognitionEngineResults( const SpeechRecognitionResults& results) { FSMEventArgs event_args(EVENT_ENGINE_RESULT); event_args.engine_results = results; BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, - base::Bind(&SpeechRecognizer::DispatchEvent, + base::Bind(&SpeechRecognizerImpl::DispatchEvent, this, event_args)); } -void SpeechRecognizer::OnSpeechRecognitionEngineError( +void SpeechRecognizerImpl::OnSpeechRecognitionEngineError( const SpeechRecognitionError& error) { FSMEventArgs event_args(EVENT_ENGINE_ERROR); event_args.engine_error = error; BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, - base::Bind(&SpeechRecognizer::DispatchEvent, + base::Bind(&SpeechRecognizerImpl::DispatchEvent, this, event_args)); } @@ -214,7 +210,7 @@ void SpeechRecognizer::OnSpeechRecognitionEngineError( // TestAudioInputController is not closing asynchronously as the real controller // does, but they will become flaky if TestAudioInputController will be fixed. -void SpeechRecognizer::DispatchEvent(const FSMEventArgs& event_args) { +void SpeechRecognizerImpl::DispatchEvent(const FSMEventArgs& event_args) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); DCHECK_LE(event_args.event, EVENT_MAX_VALUE); DCHECK_LE(state_, STATE_MAX_VALUE); @@ -225,7 +221,7 @@ void SpeechRecognizer::DispatchEvent(const FSMEventArgs& event_args) { is_dispatching_event_ = true; // Guard against the delegate freeing us until we finish processing the event. - scoped_refptr<SpeechRecognizer> me(this); + scoped_refptr<SpeechRecognizerImpl> me(this); if (event_args.event == EVENT_AUDIO_DATA) { DCHECK(event_args.audio_data.get() != NULL); @@ -238,8 +234,8 @@ void SpeechRecognizer::DispatchEvent(const FSMEventArgs& event_args) { is_dispatching_event_ = false; } -SpeechRecognizer::FSMState -SpeechRecognizer::ExecuteTransitionAndGetNextState( +SpeechRecognizerImpl::FSMState +SpeechRecognizerImpl::ExecuteTransitionAndGetNextState( const FSMEventArgs& event_args) { const FSMEvent event = event_args.event; switch (state_) { @@ -358,7 +354,7 @@ SpeechRecognizer::ExecuteTransitionAndGetNextState( // TODO(primiano): the audio pipeline is currently serial. However, the // clipper->endpointer->vumeter chain and the sr_engine could be parallelized. // We should profile the execution to see if it would be worth or not. -void SpeechRecognizer::ProcessAudioPipeline(const AudioChunk& raw_audio) { +void SpeechRecognizerImpl::ProcessAudioPipeline(const AudioChunk& raw_audio) { const bool route_to_endpointer = state_ >= STATE_ESTIMATING_ENVIRONMENT && state_ <= STATE_RECOGNIZING; const bool route_to_sr_engine = route_to_endpointer; @@ -382,8 +378,8 @@ void SpeechRecognizer::ProcessAudioPipeline(const AudioChunk& raw_audio) { } } -SpeechRecognizer::FSMState -SpeechRecognizer::StartRecording(const FSMEventArgs&) { +SpeechRecognizerImpl::FSMState +SpeechRecognizerImpl::StartRecording(const FSMEventArgs&) { DCHECK(recognition_engine_.get() != NULL); DCHECK(!IsCapturingAudio()); AudioManager* audio_manager = (audio_manager_for_tests_ != NULL) ? @@ -391,7 +387,7 @@ SpeechRecognizer::StartRecording(const FSMEventArgs&) { BrowserMainLoop::GetAudioManager(); DCHECK(audio_manager != NULL); - DVLOG(1) << "SpeechRecognizer starting audio capture."; + DVLOG(1) << "SpeechRecognizerImpl starting audio capture."; num_samples_recorded_ = 0; audio_level_ = 0; listener_->OnRecognitionStart(session_id_); @@ -426,8 +422,8 @@ SpeechRecognizer::StartRecording(const FSMEventArgs&) { return STATE_STARTING; } -SpeechRecognizer::FSMState -SpeechRecognizer::StartRecognitionEngine(const FSMEventArgs& event_args) { +SpeechRecognizerImpl::FSMState +SpeechRecognizerImpl::StartRecognitionEngine(const FSMEventArgs& event_args) { // This is the first audio packet captured, so the recognition engine is // started and the delegate notified about the event. DCHECK(recognition_engine_.get() != NULL); @@ -441,8 +437,8 @@ SpeechRecognizer::StartRecognitionEngine(const FSMEventArgs& event_args) { return STATE_ESTIMATING_ENVIRONMENT; } -SpeechRecognizer::FSMState -SpeechRecognizer::WaitEnvironmentEstimationCompletion(const FSMEventArgs&) { +SpeechRecognizerImpl::FSMState +SpeechRecognizerImpl::WaitEnvironmentEstimationCompletion(const FSMEventArgs&) { DCHECK(endpointer_.IsEstimatingEnvironment()); if (GetElapsedTimeMs() >= kEndpointerEstimationTimeMs) { endpointer_.SetUserInputMode(); @@ -453,8 +449,8 @@ SpeechRecognizer::WaitEnvironmentEstimationCompletion(const FSMEventArgs&) { } } -SpeechRecognizer::FSMState -SpeechRecognizer::DetectUserSpeechOrTimeout(const FSMEventArgs&) { +SpeechRecognizerImpl::FSMState +SpeechRecognizerImpl::DetectUserSpeechOrTimeout(const FSMEventArgs&) { if (endpointer_.DidStartReceivingSpeech()) { listener_->OnSoundStart(session_id_); return STATE_RECOGNIZING; @@ -464,15 +460,15 @@ SpeechRecognizer::DetectUserSpeechOrTimeout(const FSMEventArgs&) { return STATE_WAITING_FOR_SPEECH; } -SpeechRecognizer::FSMState -SpeechRecognizer::DetectEndOfSpeech(const FSMEventArgs& event_args) { +SpeechRecognizerImpl::FSMState +SpeechRecognizerImpl::DetectEndOfSpeech(const FSMEventArgs& event_args) { if (endpointer_.speech_input_complete()) return StopCaptureAndWaitForResult(event_args); return STATE_RECOGNIZING; } -SpeechRecognizer::FSMState -SpeechRecognizer::StopCaptureAndWaitForResult(const FSMEventArgs&) { +SpeechRecognizerImpl::FSMState +SpeechRecognizerImpl::StopCaptureAndWaitForResult(const FSMEventArgs&) { DCHECK(state_ >= STATE_ESTIMATING_ENVIRONMENT && state_ <= STATE_RECOGNIZING); DVLOG(1) << "Concluding recognition"; @@ -486,15 +482,15 @@ SpeechRecognizer::StopCaptureAndWaitForResult(const FSMEventArgs&) { return STATE_WAITING_FINAL_RESULT; } -SpeechRecognizer::FSMState -SpeechRecognizer::AbortSilently(const FSMEventArgs& event_args) { +SpeechRecognizerImpl::FSMState +SpeechRecognizerImpl::AbortSilently(const FSMEventArgs& event_args) { DCHECK_NE(event_args.event, EVENT_AUDIO_ERROR); DCHECK_NE(event_args.event, EVENT_ENGINE_ERROR); return Abort(SpeechRecognitionError(SPEECH_RECOGNITION_ERROR_NONE)); } -SpeechRecognizer::FSMState -SpeechRecognizer::AbortWithError(const FSMEventArgs& event_args) { +SpeechRecognizerImpl::FSMState +SpeechRecognizerImpl::AbortWithError(const FSMEventArgs& event_args) { if (event_args.event == EVENT_AUDIO_ERROR) { return Abort(SpeechRecognitionError(SPEECH_RECOGNITION_ERROR_AUDIO)); } else if (event_args.event == EVENT_ENGINE_ERROR) { @@ -503,12 +499,12 @@ SpeechRecognizer::AbortWithError(const FSMEventArgs& event_args) { return Abort(SpeechRecognitionError(SPEECH_RECOGNITION_ERROR_ABORTED)); } -SpeechRecognizer::FSMState SpeechRecognizer::Abort( +SpeechRecognizerImpl::FSMState SpeechRecognizerImpl::Abort( const SpeechRecognitionError& error) { if (IsCapturingAudio()) CloseAudioControllerAsynchronously(); - DVLOG(1) << "SpeechRecognizer canceling recognition. "; + DVLOG(1) << "SpeechRecognizerImpl canceling recognition. "; // The recognition engine is initialized only after STATE_STARTING. if (state_ > STATE_STARTING) { @@ -530,7 +526,7 @@ SpeechRecognizer::FSMState SpeechRecognizer::Abort( return STATE_IDLE; } -SpeechRecognizer::FSMState SpeechRecognizer::ProcessIntermediateResult( +SpeechRecognizerImpl::FSMState SpeechRecognizerImpl::ProcessIntermediateResult( const FSMEventArgs& event_args) { // Provisional results can occur only during continuous (non one-shot) mode. // If this check is reached it means that a continuous speech recognition @@ -556,8 +552,8 @@ SpeechRecognizer::FSMState SpeechRecognizer::ProcessIntermediateResult( return STATE_RECOGNIZING; } -SpeechRecognizer::FSMState -SpeechRecognizer::ProcessFinalResult(const FSMEventArgs& event_args) { +SpeechRecognizerImpl::FSMState +SpeechRecognizerImpl::ProcessFinalResult(const FSMEventArgs& event_args) { const SpeechRecognitionResults& results = event_args.engine_results; SpeechRecognitionResults::const_iterator i = results.begin(); bool provisional_results_pending = false; @@ -599,35 +595,35 @@ SpeechRecognizer::ProcessFinalResult(const FSMEventArgs& event_args) { return STATE_IDLE; } -SpeechRecognizer::FSMState -SpeechRecognizer::DoNothing(const FSMEventArgs&) const { +SpeechRecognizerImpl::FSMState +SpeechRecognizerImpl::DoNothing(const FSMEventArgs&) const { return state_; // Just keep the current state. } -SpeechRecognizer::FSMState -SpeechRecognizer::NotFeasible(const FSMEventArgs& event_args) { +SpeechRecognizerImpl::FSMState +SpeechRecognizerImpl::NotFeasible(const FSMEventArgs& event_args) { NOTREACHED() << "Unfeasible event " << event_args.event << " in state " << state_; return state_; } -void SpeechRecognizer::CloseAudioControllerAsynchronously() { +void SpeechRecognizerImpl::CloseAudioControllerAsynchronously() { DCHECK(IsCapturingAudio()); - DVLOG(1) << "SpeechRecognizer closing audio controller."; + DVLOG(1) << "SpeechRecognizerImpl closing audio controller."; // Issues a Close on the audio controller, passing an empty callback. The only // purpose of such callback is to keep the audio controller refcounted until // Close has completed (in the audio thread) and automatically destroy it // afterwards (upon return from OnAudioClosed). - audio_controller_->Close(base::Bind(&SpeechRecognizer::OnAudioClosed, + audio_controller_->Close(base::Bind(&SpeechRecognizerImpl::OnAudioClosed, this, audio_controller_)); audio_controller_ = NULL; // The controller is still refcounted by Bind. } -int SpeechRecognizer::GetElapsedTimeMs() const { +int SpeechRecognizerImpl::GetElapsedTimeMs() const { return (num_samples_recorded_ * 1000) / kAudioSampleRate; } -void SpeechRecognizer::UpdateSignalAndNoiseLevels(const float& rms, +void SpeechRecognizerImpl::UpdateSignalAndNoiseLevels(const float& rms, bool clip_detected) { // Calculate the input volume to display in the UI, smoothing towards the // new level. @@ -649,18 +645,18 @@ void SpeechRecognizer::UpdateSignalAndNoiseLevels(const float& rms, session_id_, clip_detected ? 1.0f : audio_level_, noise_level); } -void SpeechRecognizer::SetAudioManagerForTests( +void SpeechRecognizerImpl::SetAudioManagerForTests( AudioManager* audio_manager) { audio_manager_for_tests_ = audio_manager; } -SpeechRecognizer::FSMEventArgs::FSMEventArgs(FSMEvent event_value) +SpeechRecognizerImpl::FSMEventArgs::FSMEventArgs(FSMEvent event_value) : event(event_value), audio_data(NULL), engine_error(SPEECH_RECOGNITION_ERROR_NONE) { } -SpeechRecognizer::FSMEventArgs::~FSMEventArgs() { +SpeechRecognizerImpl::FSMEventArgs::~FSMEventArgs() { } } // namespace content diff --git a/content/browser/speech/speech_recognizer_impl.h b/content/browser/speech/speech_recognizer_impl.h new file mode 100644 index 0000000000..2397716bd0 --- /dev/null +++ b/content/browser/speech/speech_recognizer_impl.h @@ -0,0 +1,156 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_SPEECH_SPEECH_RECOGNIZER_IMPL_H_ +#define CONTENT_BROWSER_SPEECH_SPEECH_RECOGNIZER_IMPL_H_ + +#include "base/basictypes.h" +#include "base/memory/scoped_ptr.h" +#include "content/browser/speech/endpointer/endpointer.h" +#include "content/browser/speech/speech_recognition_engine.h" +#include "content/browser/speech/speech_recognizer.h" +#include "content/public/common/speech_recognition_error.h" +#include "content/public/common/speech_recognition_result.h" +#include "media/audio/audio_input_controller.h" +#include "net/url_request/url_request_context_getter.h" + +namespace media { +class AudioManager; +} + +namespace content { + +class SpeechRecognitionEventListener; + +// Handles speech recognition for a session (identified by |session_id|), taking +// care of audio capture, silence detection/endpointer and interaction with the +// SpeechRecognitionEngine. +class CONTENT_EXPORT SpeechRecognizerImpl + : public SpeechRecognizer, + public media::AudioInputController::EventHandler, + public NON_EXPORTED_BASE(SpeechRecognitionEngineDelegate) { + public: + static const int kAudioSampleRate; + static const media::ChannelLayout kChannelLayout; + static const int kNumBitsPerAudioSample; + static const int kNoSpeechTimeoutMs; + static const int kEndpointerEstimationTimeMs; + + static void SetAudioManagerForTests(media::AudioManager* audio_manager); + + SpeechRecognizerImpl(SpeechRecognitionEventListener* listener, + int session_id, + bool is_single_shot, + SpeechRecognitionEngine* engine); + + virtual void StartRecognition() OVERRIDE; + virtual void AbortRecognition() OVERRIDE; + virtual void StopAudioCapture() OVERRIDE; + virtual bool IsActive() const OVERRIDE; + virtual bool IsCapturingAudio() const OVERRIDE; + const SpeechRecognitionEngine& recognition_engine() const; + + private: + friend class SpeechRecognizerTest; + + enum FSMState { + STATE_IDLE = 0, + STATE_STARTING, + STATE_ESTIMATING_ENVIRONMENT, + STATE_WAITING_FOR_SPEECH, + STATE_RECOGNIZING, + STATE_WAITING_FINAL_RESULT, + STATE_MAX_VALUE = STATE_WAITING_FINAL_RESULT + }; + + enum FSMEvent { + EVENT_ABORT = 0, + EVENT_START, + EVENT_STOP_CAPTURE, + EVENT_AUDIO_DATA, + EVENT_ENGINE_RESULT, + EVENT_ENGINE_ERROR, + EVENT_AUDIO_ERROR, + EVENT_MAX_VALUE = EVENT_AUDIO_ERROR + }; + + struct FSMEventArgs { + explicit FSMEventArgs(FSMEvent event_value); + ~FSMEventArgs(); + + FSMEvent event; + scoped_refptr<AudioChunk> audio_data; + SpeechRecognitionResults engine_results; + SpeechRecognitionError engine_error; + }; + + virtual ~SpeechRecognizerImpl(); + + // Entry point for pushing any new external event into the recognizer FSM. + void DispatchEvent(const FSMEventArgs& event_args); + + // Defines the behavior of the recognizer FSM, selecting the appropriate + // transition according to the current state and event. + FSMState ExecuteTransitionAndGetNextState(const FSMEventArgs& args); + + // Process a new audio chunk in the audio pipeline (endpointer, vumeter, etc). + void ProcessAudioPipeline(const AudioChunk& raw_audio); + + // The methods below handle transitions of the recognizer FSM. + FSMState StartRecording(const FSMEventArgs& event_args); + FSMState StartRecognitionEngine(const FSMEventArgs& event_args); + FSMState WaitEnvironmentEstimationCompletion(const FSMEventArgs& event_args); + FSMState DetectUserSpeechOrTimeout(const FSMEventArgs& event_args); + FSMState StopCaptureAndWaitForResult(const FSMEventArgs& event_args); + FSMState ProcessIntermediateResult(const FSMEventArgs& event_args); + FSMState ProcessFinalResult(const FSMEventArgs& event_args); + FSMState AbortSilently(const FSMEventArgs& event_args); + FSMState AbortWithError(const FSMEventArgs& event_args); + FSMState Abort(const SpeechRecognitionError& error); + FSMState DetectEndOfSpeech(const FSMEventArgs& event_args); + FSMState DoNothing(const FSMEventArgs& event_args) const; + FSMState NotFeasible(const FSMEventArgs& event_args); + + // Returns the time span of captured audio samples since the start of capture. + int GetElapsedTimeMs() const; + + // Calculates the input volume to be displayed in the UI, triggering the + // OnAudioLevelsChange event accordingly. + void UpdateSignalAndNoiseLevels(const float& rms, bool clip_detected); + + void CloseAudioControllerAsynchronously(); + + // Callback called on IO thread by audio_controller->Close(). + void OnAudioClosed(media::AudioInputController*); + + // AudioInputController::EventHandler methods. + virtual void OnCreated(media::AudioInputController* controller) OVERRIDE {} + virtual void OnRecording(media::AudioInputController* controller) OVERRIDE {} + virtual void OnError(media::AudioInputController* controller) OVERRIDE; + virtual void OnData(media::AudioInputController* controller, + const uint8* data, uint32 size) OVERRIDE; + + // SpeechRecognitionEngineDelegate methods. + virtual void OnSpeechRecognitionEngineResults( + const SpeechRecognitionResults& results) OVERRIDE; + virtual void OnSpeechRecognitionEngineError( + const SpeechRecognitionError& error) OVERRIDE; + + static media::AudioManager* audio_manager_for_tests_; + + scoped_ptr<SpeechRecognitionEngine> recognition_engine_; + Endpointer endpointer_; + scoped_refptr<media::AudioInputController> audio_controller_; + int num_samples_recorded_; + float audio_level_; + bool is_dispatching_event_; + bool is_single_shot_; + FSMState state_; + + DISALLOW_COPY_AND_ASSIGN(SpeechRecognizerImpl); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_SPEECH_SPEECH_RECOGNIZER_IMPL_H_ diff --git a/content/browser/speech/speech_recognizer_unittest.cc b/content/browser/speech/speech_recognizer_impl_unittest.cc index 9b55ec5ec3..8c7c2d7a62 100644 --- a/content/browser/speech/speech_recognizer_unittest.cc +++ b/content/browser/speech/speech_recognizer_impl_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -6,11 +6,11 @@ #include "content/browser/browser_thread_impl.h" #include "content/browser/speech/google_one_shot_remote_engine.h" -#include "content/browser/speech/speech_recognizer.h" +#include "content/browser/speech/speech_recognizer_impl.h" #include "content/public/browser/speech_recognition_event_listener.h" -#include "media/audio/mock_audio_manager.h" #include "media/audio/fake_audio_input_stream.h" #include "media/audio/fake_audio_output_stream.h" +#include "media/audio/mock_audio_manager.h" #include "media/audio/test_audio_input_controller_factory.h" #include "net/base/net_errors.h" #include "net/url_request/test_url_fetcher_factory.h" @@ -28,10 +28,10 @@ using media::TestAudioInputControllerFactory; namespace content { -class SpeechRecognizerTest : public SpeechRecognitionEventListener, - public testing::Test { +class SpeechRecognizerImplTest : public SpeechRecognitionEventListener, + public testing::Test { public: - SpeechRecognizerTest() + SpeechRecognizerImplTest() : io_thread_(BrowserThread::IO, &message_loop_), recognition_started_(false), recognition_ended_(false), @@ -46,24 +46,25 @@ class SpeechRecognizerTest : public SpeechRecognitionEventListener, SpeechRecognitionEngine* sr_engine = new GoogleOneShotRemoteEngine(NULL /* URLRequestContextGetter */); SpeechRecognitionEngineConfig config; - config.audio_num_bits_per_sample = SpeechRecognizer::kNumBitsPerAudioSample; - config.audio_sample_rate = SpeechRecognizer::kAudioSampleRate; + config.audio_num_bits_per_sample = + SpeechRecognizerImpl::kNumBitsPerAudioSample; + config.audio_sample_rate = SpeechRecognizerImpl::kAudioSampleRate; config.filter_profanities = false; sr_engine->SetConfig(config); const int kTestingSessionId = 1; const bool kOneShotMode = true; - recognizer_ = new SpeechRecognizer( + recognizer_ = new SpeechRecognizerImpl( this, kTestingSessionId, kOneShotMode, sr_engine); audio_manager_.reset(new media::MockAudioManager( base::MessageLoop::current()->message_loop_proxy())); recognizer_->SetAudioManagerForTests(audio_manager_.get()); int audio_packet_length_bytes = - (SpeechRecognizer::kAudioSampleRate * + (SpeechRecognizerImpl::kAudioSampleRate * GoogleOneShotRemoteEngine::kAudioPacketIntervalMs * - ChannelLayoutToChannelCount(SpeechRecognizer::kChannelLayout) * - SpeechRecognizer::kNumBitsPerAudioSample) / (8 * 1000); + ChannelLayoutToChannelCount(SpeechRecognizerImpl::kChannelLayout) * + SpeechRecognizerImpl::kNumBitsPerAudioSample) / (8 * 1000); audio_packet_.resize(audio_packet_length_bytes); } @@ -164,7 +165,7 @@ class SpeechRecognizerTest : public SpeechRecognitionEventListener, protected: base::MessageLoopForIO message_loop_; BrowserThreadImpl io_thread_; - scoped_refptr<SpeechRecognizer> recognizer_; + scoped_refptr<SpeechRecognizerImpl> recognizer_; scoped_ptr<AudioManager> audio_manager_; bool recognition_started_; bool recognition_ended_; @@ -181,7 +182,7 @@ class SpeechRecognizerTest : public SpeechRecognitionEventListener, float noise_volume_; }; -TEST_F(SpeechRecognizerTest, StopNoData) { +TEST_F(SpeechRecognizerImplTest, StopNoData) { // Check for callbacks when stopping record before any audio gets recorded. recognizer_->StartRecognition(); recognizer_->StopAudioCapture(); @@ -193,7 +194,7 @@ TEST_F(SpeechRecognizerTest, StopNoData) { CheckFinalEventsConsistency(); } -TEST_F(SpeechRecognizerTest, CancelNoData) { +TEST_F(SpeechRecognizerImplTest, CancelNoData) { // Check for callbacks when canceling recognition before any audio gets // recorded. recognizer_->StartRecognition(); @@ -206,7 +207,7 @@ TEST_F(SpeechRecognizerTest, CancelNoData) { CheckFinalEventsConsistency(); } -TEST_F(SpeechRecognizerTest, StopWithData) { +TEST_F(SpeechRecognizerImplTest, StopWithData) { // Start recording, give some data and then stop. This should wait for the // network callback to arrive before completion. recognizer_->StartRecognition(); @@ -256,7 +257,7 @@ TEST_F(SpeechRecognizerTest, StopWithData) { CheckFinalEventsConsistency(); } -TEST_F(SpeechRecognizerTest, CancelWithData) { +TEST_F(SpeechRecognizerImplTest, CancelWithData) { // Start recording, give some data and then cancel. recognizer_->StartRecognition(); base::MessageLoop::current()->RunUntilIdle(); @@ -276,7 +277,7 @@ TEST_F(SpeechRecognizerTest, CancelWithData) { CheckFinalEventsConsistency(); } -TEST_F(SpeechRecognizerTest, ConnectionError) { +TEST_F(SpeechRecognizerImplTest, ConnectionError) { // Start recording, give some data and then stop. Issue the network callback // with a connection error and verify that the recognizer bubbles the error up recognizer_->StartRecognition(); @@ -314,7 +315,7 @@ TEST_F(SpeechRecognizerTest, ConnectionError) { CheckFinalEventsConsistency(); } -TEST_F(SpeechRecognizerTest, ServerError) { +TEST_F(SpeechRecognizerImplTest, ServerError) { // Start recording, give some data and then stop. Issue the network callback // with a 500 error and verify that the recognizer bubbles the error up recognizer_->StartRecognition(); @@ -351,7 +352,7 @@ TEST_F(SpeechRecognizerTest, ServerError) { CheckFinalEventsConsistency(); } -TEST_F(SpeechRecognizerTest, AudioControllerErrorNoData) { +TEST_F(SpeechRecognizerImplTest, AudioControllerErrorNoData) { // Check if things tear down properly if AudioInputController threw an error. recognizer_->StartRecognition(); base::MessageLoop::current()->RunUntilIdle(); @@ -367,7 +368,7 @@ TEST_F(SpeechRecognizerTest, AudioControllerErrorNoData) { CheckFinalEventsConsistency(); } -TEST_F(SpeechRecognizerTest, AudioControllerErrorWithData) { +TEST_F(SpeechRecognizerImplTest, AudioControllerErrorWithData) { // Check if things tear down properly if AudioInputController threw an error // after giving some audio data. recognizer_->StartRecognition(); @@ -387,7 +388,7 @@ TEST_F(SpeechRecognizerTest, AudioControllerErrorWithData) { CheckFinalEventsConsistency(); } -TEST_F(SpeechRecognizerTest, NoSpeechCallbackIssued) { +TEST_F(SpeechRecognizerImplTest, NoSpeechCallbackIssued) { // Start recording and give a lot of packets with audio samples set to zero. // This should trigger the no-speech detector and issue a callback. recognizer_->StartRecognition(); @@ -396,7 +397,7 @@ TEST_F(SpeechRecognizerTest, NoSpeechCallbackIssued) { audio_input_controller_factory_.controller(); ASSERT_TRUE(controller); - int num_packets = (SpeechRecognizer::kNoSpeechTimeoutMs) / + int num_packets = (SpeechRecognizerImpl::kNoSpeechTimeoutMs) / GoogleOneShotRemoteEngine::kAudioPacketIntervalMs + 1; // The vector is already filled with zero value samples on create. for (int i = 0; i < num_packets; ++i) { @@ -411,7 +412,7 @@ TEST_F(SpeechRecognizerTest, NoSpeechCallbackIssued) { CheckFinalEventsConsistency(); } -TEST_F(SpeechRecognizerTest, NoSpeechCallbackNotIssued) { +TEST_F(SpeechRecognizerImplTest, NoSpeechCallbackNotIssued) { // Start recording and give a lot of packets with audio samples set to zero // and then some more with reasonably loud audio samples. This should be // treated as normal speech input and the no-speech detector should not get @@ -424,7 +425,7 @@ TEST_F(SpeechRecognizerTest, NoSpeechCallbackNotIssued) { controller = audio_input_controller_factory_.controller(); ASSERT_TRUE(controller); - int num_packets = (SpeechRecognizer::kNoSpeechTimeoutMs) / + int num_packets = (SpeechRecognizerImpl::kNoSpeechTimeoutMs) / GoogleOneShotRemoteEngine::kAudioPacketIntervalMs; // The vector is already filled with zero value samples on create. @@ -449,7 +450,7 @@ TEST_F(SpeechRecognizerTest, NoSpeechCallbackNotIssued) { CheckFinalEventsConsistency(); } -TEST_F(SpeechRecognizerTest, SetInputVolumeCallback) { +TEST_F(SpeechRecognizerImplTest, SetInputVolumeCallback) { // Start recording and give a lot of packets with audio samples set to zero // and then some more with reasonably loud audio samples. Check that we don't // get the callback during estimation phase, then get zero for the silence @@ -463,7 +464,7 @@ TEST_F(SpeechRecognizerTest, SetInputVolumeCallback) { ASSERT_TRUE(controller); // Feed some samples to begin with for the endpointer to do noise estimation. - int num_packets = SpeechRecognizer::kEndpointerEstimationTimeMs / + int num_packets = SpeechRecognizerImpl::kEndpointerEstimationTimeMs / GoogleOneShotRemoteEngine::kAudioPacketIntervalMs; FillPacketWithNoise(); for (int i = 0; i < num_packets; ++i) { diff --git a/content/browser/ssl/ssl_policy.cc b/content/browser/ssl/ssl_policy.cc index 1b0e4245a8..1b9d60c9ac 100644 --- a/content/browser/ssl/ssl_policy.cc +++ b/content/browser/ssl/ssl_policy.cc @@ -194,7 +194,8 @@ void SSLPolicy::OnAllowCertificate(scoped_refptr<SSLCertErrorHandler> handler, void SSLPolicy::OnCertErrorInternal(SSLCertErrorHandler* handler, bool overridable, bool strict_enforcement) { - bool cancel_request = false; + CertificateRequestResultType result = + CERTIFICATE_REQUEST_RESULT_TYPE_CONTINUE; GetContentClient()->browser()->AllowCertificateError( handler->render_process_id(), handler->render_view_id(), @@ -206,9 +207,19 @@ void SSLPolicy::OnCertErrorInternal(SSLCertErrorHandler* handler, strict_enforcement, base::Bind(&SSLPolicy::OnAllowCertificate, base::Unretained(this), make_scoped_refptr(handler)), - &cancel_request); - if (cancel_request) - handler->CancelRequest(); + &result); + switch (result) { + case CERTIFICATE_REQUEST_RESULT_TYPE_CONTINUE: + break; + case CERTIFICATE_REQUEST_RESULT_TYPE_CANCEL: + handler->CancelRequest(); + break; + case CERTIFICATE_REQUEST_RESULT_TYPE_DENY: + handler->DenyRequest(); + break; + default: + NOTREACHED(); + } } void SSLPolicy::InitializeEntryIfNeeded(NavigationEntryImpl* entry) { diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc index ab0e7a5672..f982f76c79 100644 --- a/content/browser/storage_partition_impl.cc +++ b/content/browser/storage_partition_impl.cc @@ -16,7 +16,7 @@ #include "net/cookies/cookie_monster.h" #include "net/url_request/url_request_context_getter.h" #include "net/url_request/url_request_context.h" -#include "webkit/database/database_tracker.h" +#include "webkit/browser/database/database_tracker.h" #include "webkit/dom_storage/dom_storage_types.h" #include "webkit/quota/quota_manager.h" diff --git a/content/browser/storage_partition_impl_map.cc b/content/browser/storage_partition_impl_map.cc index 94141d6179..400c3b1f8f 100644 --- a/content/browser/storage_partition_impl_map.cc +++ b/content/browser/storage_partition_impl_map.cc @@ -33,9 +33,9 @@ #include "crypto/sha2.h" #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context_getter.h" -#include "webkit/blob/blob_data.h" -#include "webkit/blob/blob_url_request_job_factory.h" -#include "webkit/fileapi/file_system_url_request_job_factory.h" +#include "webkit/browser/blob/blob_url_request_job_factory.h" +#include "webkit/browser/fileapi/file_system_url_request_job_factory.h" +#include "webkit/common/blob/blob_data.h" using appcache::AppCacheService; using fileapi::FileSystemContext; diff --git a/content/browser/tracing/tracing_ui.cc b/content/browser/tracing/tracing_ui.cc index 5b7e359651..f14578eb00 100644 --- a/content/browser/tracing/tracing_ui.cc +++ b/content/browser/tracing/tracing_ui.cc @@ -11,6 +11,7 @@ #include "base/command_line.h" #include "base/debug/trace_event.h" #include "base/file_util.h" +#include "base/json/string_escape.h" #include "base/memory/scoped_ptr.h" #include "base/string_util.h" #include "base/stringprintf.h" @@ -88,7 +89,8 @@ class TracingMessageHandler void OnGetKnownCategories(const base::ListValue* list); // Callbacks. - void LoadTraceFileComplete(string16* file_contents); + void LoadTraceFileComplete(string16* file_contents, + const base::FilePath &path); void SaveTraceFileComplete(); private: @@ -120,9 +122,10 @@ class TaskProxy : public base::RefCountedThreadSafe<TaskProxy> { public: explicit TaskProxy(const base::WeakPtr<TracingMessageHandler>& handler) : handler_(handler) {} - void LoadTraceFileCompleteProxy(string16* file_contents) { + void LoadTraceFileCompleteProxy(string16* file_contents, + const base::FilePath& path) { if (handler_) - handler_->LoadTraceFileComplete(file_contents); + handler_->LoadTraceFileComplete(file_contents, path); delete file_contents; } @@ -257,7 +260,8 @@ void ReadTraceFileCallback(TaskProxy* proxy, const base::FilePath& path) { BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, base::Bind(&TaskProxy::LoadTraceFileCompleteProxy, proxy, - contents16.release())); + contents16.release(), + path)); } // A callback used for asynchronously writing a file from a string. Calls the @@ -324,7 +328,8 @@ void TracingMessageHandler::OnLoadTraceFile(const base::ListValue* list) { NULL); } -void TracingMessageHandler::LoadTraceFileComplete(string16* contents) { +void TracingMessageHandler::LoadTraceFileComplete(string16* contents, + const base::FilePath& path) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); // We need to pass contents to tracingController.onLoadTraceFileComplete, but @@ -344,8 +349,12 @@ void TracingMessageHandler::LoadTraceFileComplete(string16* contents) { javascript += contents->substr(i, kMaxSize) + suffix; rvh->ExecuteJavascriptInWebFrame(string16(), javascript); } + + // The CallJavascriptFunction is not used because we need to pass + // the first param |window.traceData| through as an un-quoted string. rvh->ExecuteJavascriptInWebFrame(string16(), UTF8ToUTF16( - "tracingController.onLoadTraceFileComplete(window.traceData);" + "tracingController.onLoadTraceFileComplete(window.traceData," + + base::GetDoubleQuotedJson(path.value()) + ");" + "delete window.traceData;")); } @@ -487,16 +496,15 @@ void TracingMessageHandler::OnTraceDataCollected( const scoped_refptr<base::RefCountedString>& trace_fragment) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - std::string javascript("window.traceData += '"); - - std::string escaped_data; - ReplaceChars(trace_fragment->data(), "\\", "\\\\", &escaped_data); - javascript += escaped_data; + std::string javascript; + javascript.reserve(trace_fragment->size() * 2); + javascript.append("window.traceData += \""); + base::JsonDoubleQuote(trace_fragment->data(), false, &javascript); // Intentionally append a , to the traceData. This technically causes all // traceData that we pass back to JS to end with a comma, but that is actually // something the JS side strips away anyway - javascript += ",';"; + javascript.append(",\";"); web_ui()->GetWebContents()->GetRenderViewHost()-> ExecuteJavascriptInWebFrame(string16(), UTF8ToUTF16(javascript)); @@ -522,7 +530,7 @@ void TracingMessageHandler::OnKnownCategoriesCollected( DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); scoped_ptr<base::ListValue> categories(new base::ListValue()); - for (std::set<std::string>::iterator iter = known_categories.begin(); + for (std::set<std::string>::const_iterator iter = known_categories.begin(); iter != known_categories.end(); ++iter) { categories->AppendString(*iter); diff --git a/content/browser/web_contents/interstitial_page_impl.cc b/content/browser/web_contents/interstitial_page_impl.cc index 9673e98069..9b6ada982f 100644 --- a/content/browser/web_contents/interstitial_page_impl.cc +++ b/content/browser/web_contents/interstitial_page_impl.cc @@ -135,7 +135,8 @@ InterstitialPageImpl::InterstitialPageImpl(WebContents* web_contents, bool new_navigation, const GURL& url, InterstitialPageDelegate* delegate) - : web_contents_(static_cast<WebContentsImpl*>(web_contents)), + : WebContentsObserver(web_contents), + web_contents_(static_cast<WebContentsImpl*>(web_contents)), url_(url), new_navigation_(new_navigation), should_discard_pending_nav_entry_(new_navigation), @@ -224,9 +225,6 @@ void InterstitialPageImpl::Show() { net::EscapePath(delegate_->GetHTMLContents()); render_view_host_->NavigateToURL(GURL(data_url)); - notification_registrar_.Add(this, - NOTIFICATION_WEB_CONTENTS_DESTROYED, - Source<WebContents>(web_contents_)); notification_registrar_.Add(this, NOTIFICATION_NAV_ENTRY_COMMITTED, Source<NavigationController>(&web_contents_->GetController())); notification_registrar_.Add(this, NOTIFICATION_NAV_ENTRY_PENDING, @@ -324,19 +322,8 @@ void InterstitialPageImpl::Observe( TakeActionOnResourceDispatcher(CANCEL); } break; - case NOTIFICATION_WEB_CONTENTS_DESTROYED: case NOTIFICATION_NAV_ENTRY_COMMITTED: - if (action_taken_ == NO_ACTION) { - // We are navigating away from the interstitial or closing a tab with an - // interstitial. Default to DontProceed(). We don't just call Hide as - // subclasses will almost certainly override DontProceed to do some work - // (ex: close pending connections). - DontProceed(); - } else { - // User decided to proceed and either the navigation was committed or - // the tab was closed before that. - Hide(); - } + OnNavigatingAwayOrTabClosing(); break; case NOTIFICATION_DOM_OPERATION_RESPONSE: if (enabled()) { @@ -350,6 +337,10 @@ void InterstitialPageImpl::Observe( } } +void InterstitialPageImpl::WebContentsDestroyed(WebContents* web_contents) { + OnNavigatingAwayOrTabClosing(); +} + RenderViewHostDelegateView* InterstitialPageImpl::GetDelegateView() { return rvh_delegate_view_.get(); } @@ -721,6 +712,20 @@ void InterstitialPageImpl::Shutdown(RenderViewHostImpl* render_view_host) { // We are deleted now. } +void InterstitialPageImpl::OnNavigatingAwayOrTabClosing() { + if (action_taken_ == NO_ACTION) { + // We are navigating away from the interstitial or closing a tab with an + // interstitial. Default to DontProceed(). We don't just call Hide as + // subclasses will almost certainly override DontProceed to do some work + // (ex: close pending connections). + DontProceed(); + } else { + // User decided to proceed and either the navigation was committed or + // the tab was closed before that. + Hide(); + } +} + void InterstitialPageImpl::TakeActionOnResourceDispatcher( ResourceRequestAction action) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)) << diff --git a/content/browser/web_contents/interstitial_page_impl.h b/content/browser/web_contents/interstitial_page_impl.h index 2b3108a8e3..532dcc293f 100644 --- a/content/browser/web_contents/interstitial_page_impl.h +++ b/content/browser/web_contents/interstitial_page_impl.h @@ -14,6 +14,7 @@ #include "content/public/browser/interstitial_page.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" +#include "content/public/browser/web_contents_observer.h" #include "content/public/common/renderer_preferences.h" #include "googleurl/src/gurl.h" @@ -33,6 +34,7 @@ enum ResourceRequestAction { class CONTENT_EXPORT InterstitialPageImpl : public NON_EXPORTED_BASE(InterstitialPage), public NotificationObserver, + public WebContentsObserver, public RenderViewHostDelegate, public RenderWidgetHostDelegate { public: @@ -89,6 +91,9 @@ class CONTENT_EXPORT InterstitialPageImpl const NotificationSource& source, const NotificationDetails& details) OVERRIDE; + // WebContentsObserver implementation: + virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE; + // RenderViewHostDelegate implementation: virtual RenderViewHostDelegateView* GetDelegateView() OVERRIDE; virtual const GURL& GetURL() const OVERRIDE; @@ -162,6 +167,8 @@ class CONTENT_EXPORT InterstitialPageImpl // Shutdown the RVH. We will be deleted by the time this method returns. void Shutdown(RenderViewHostImpl* render_view_host); + void OnNavigatingAwayOrTabClosing(); + // Executes the passed action on the ResourceDispatcher (on the IO thread). // Used to block/resume/cancel requests for the RenderViewHost hidden by this // interstitial. diff --git a/content/browser/web_contents/navigation_controller_impl.cc b/content/browser/web_contents/navigation_controller_impl.cc index 5488c6c814..8bd29ee87d 100644 --- a/content/browser/web_contents/navigation_controller_impl.cc +++ b/content/browser/web_contents/navigation_controller_impl.cc @@ -40,7 +40,6 @@ #include "net/base/mime_util.h" #include "net/base/net_util.h" #include "skia/ext/platform_canvas.h" -#include "webkit/glue/glue_serialize.h" namespace content { namespace { @@ -69,11 +68,9 @@ void NotifyPrunedEntries(NavigationControllerImpl* nav_controller, // losing the navigation entries and generating a new navigation entry after // this one. We don't want that. To avoid this we create a valid state which // WebKit will not treat as a new navigation. -void SetContentStateIfEmpty(NavigationEntryImpl* entry) { - if (entry->GetContentState().empty()) { - entry->SetContentState( - webkit_glue::CreateHistoryStateForURL(entry->GetURL())); - } +void SetPageStateIfEmpty(NavigationEntryImpl* entry) { + if (!entry->GetPageState().IsValid()) + entry->SetPageState(PageState::CreateFromURL(entry->GetURL())); } NavigationEntryImpl::RestoreType ControllerRestoreTypeToEntryType( @@ -101,7 +98,7 @@ void ConfigureEntriesForRestore( (*entries)[i]->SetTransitionType(PAGE_TRANSITION_RELOAD); (*entries)[i]->set_restore_type(ControllerRestoreTypeToEntryType(type)); // NOTE(darin): This code is only needed for backwards compat. - SetContentStateIfEmpty((*entries)[i].get()); + SetPageStateIfEmpty((*entries)[i].get()); } } @@ -769,11 +766,11 @@ bool NavigationControllerImpl::RendererDidNavigate( // All committed entries should have nonempty content state so WebKit doesn't // get confused when we go back to them (see the function for details). - DCHECK(!params.content_state.empty()); + DCHECK(params.page_state.IsValid()); NavigationEntryImpl* active_entry = NavigationEntryImpl::FromNavigationEntry(GetLastCommittedEntry()); active_entry->SetTimestamp(timestamp); - active_entry->SetContentState(params.content_state); + active_entry->SetPageState(params.page_state); // No longer needed since content state will hold the post data if any. active_entry->SetBrowserInitiatedPostData(NULL); diff --git a/content/browser/web_contents/navigation_controller_impl_unittest.cc b/content/browser/web_contents/navigation_controller_impl_unittest.cc index 4a51897e64..f9c2372651 100644 --- a/content/browser/web_contents/navigation_controller_impl_unittest.cc +++ b/content/browser/web_contents/navigation_controller_impl_unittest.cc @@ -32,6 +32,7 @@ #include "content/public/browser/render_view_host.h" #include "content/public/browser/render_view_host_observer.h" #include "content/public/browser/web_contents_delegate.h" +#include "content/public/common/page_state.h" #include "content/public/test/mock_render_process_host.h" #include "content/public/test/test_notification_tracker.h" #include "content/public/test/test_utils.h" @@ -39,7 +40,6 @@ #include "net/base/net_util.h" #include "skia/ext/platform_canvas.h" #include "testing/gtest/include/gtest/gtest.h" -#include "webkit/glue/glue_serialize.h" using base::Time; @@ -1493,7 +1493,7 @@ TEST_F(NavigationControllerTest, Redirect) { params.should_update_history = false; params.gesture = NavigationGestureAuto; params.is_post = false; - params.content_state = webkit_glue::CreateHistoryStateForURL(GURL(url2)); + params.page_state = PageState::CreateFromURL(url2); LoadCommittedDetails details; @@ -1548,7 +1548,7 @@ TEST_F(NavigationControllerTest, PostThenRedirect) { params.should_update_history = false; params.gesture = NavigationGestureAuto; params.is_post = false; - params.content_state = webkit_glue::CreateHistoryStateForURL(GURL(url2)); + params.page_state = PageState::CreateFromURL(url2); LoadCommittedDetails details; @@ -1594,7 +1594,7 @@ TEST_F(NavigationControllerTest, ImmediateRedirect) { params.should_update_history = false; params.gesture = NavigationGestureAuto; params.is_post = false; - params.content_state = webkit_glue::CreateHistoryStateForURL(GURL(url2)); + params.page_state = PageState::CreateFromURL(url2); LoadCommittedDetails details; @@ -1633,7 +1633,7 @@ TEST_F(NavigationControllerTest, NewSubframe) { params.should_update_history = false; params.gesture = NavigationGestureUser; params.is_post = false; - params.content_state = webkit_glue::CreateHistoryStateForURL(GURL(url2)); + params.page_state = PageState::CreateFromURL(url2); LoadCommittedDetails details; EXPECT_TRUE(controller.RendererDidNavigate(params, &details)); @@ -1668,7 +1668,7 @@ TEST_F(NavigationControllerTest, SubframeOnEmptyPage) { params.should_update_history = false; params.gesture = NavigationGestureAuto; params.is_post = false; - params.content_state = webkit_glue::CreateHistoryStateForURL(GURL(url)); + params.page_state = PageState::CreateFromURL(url); LoadCommittedDetails details; EXPECT_FALSE(controller.RendererDidNavigate(params, &details)); @@ -1694,7 +1694,7 @@ TEST_F(NavigationControllerTest, AutoSubframe) { params.should_update_history = false; params.gesture = NavigationGestureUser; params.is_post = false; - params.content_state = webkit_glue::CreateHistoryStateForURL(GURL(url2)); + params.page_state = PageState::CreateFromURL(url2); // Navigating should do nothing. LoadCommittedDetails details; @@ -1725,7 +1725,7 @@ TEST_F(NavigationControllerTest, BackSubframe) { params.should_update_history = false; params.gesture = NavigationGestureUser; params.is_post = false; - params.content_state = webkit_glue::CreateHistoryStateForURL(GURL(url2)); + params.page_state = PageState::CreateFromURL(url2); // This should generate a new entry. LoadCommittedDetails details; @@ -1808,7 +1808,7 @@ TEST_F(NavigationControllerTest, InPage) { self_params.should_update_history = false; self_params.gesture = NavigationGestureUser; self_params.is_post = false; - self_params.content_state = webkit_glue::CreateHistoryStateForURL(GURL(url1)); + self_params.page_state = PageState::CreateFromURL(url1); self_params.was_within_same_page = true; LoadCommittedDetails details; @@ -1827,7 +1827,7 @@ TEST_F(NavigationControllerTest, InPage) { params.should_update_history = false; params.gesture = NavigationGestureUser; params.is_post = false; - params.content_state = webkit_glue::CreateHistoryStateForURL(GURL(url2)); + params.page_state = PageState::CreateFromURL(url2); // This should generate a new entry. EXPECT_TRUE(controller.RendererDidNavigate(params, &details)); @@ -1905,7 +1905,7 @@ TEST_F(NavigationControllerTest, InPage_Replace) { params.should_update_history = false; params.gesture = NavigationGestureUser; params.is_post = false; - params.content_state = webkit_glue::CreateHistoryStateForURL(GURL(url2)); + params.page_state = PageState::CreateFromURL(url2); // This should NOT generate a new entry, nor prune the list. LoadCommittedDetails details; @@ -1952,7 +1952,7 @@ TEST_F(NavigationControllerTest, ClientRedirectAfterInPageNavigation) { params.should_update_history = true; params.gesture = NavigationGestureUnknown; params.is_post = false; - params.content_state = webkit_glue::CreateHistoryStateForURL(GURL(url)); + params.page_state = PageState::CreateFromURL(url); // This should NOT generate a new entry, nor prune the list. LoadCommittedDetails details; @@ -1975,7 +1975,7 @@ TEST_F(NavigationControllerTest, ClientRedirectAfterInPageNavigation) { params.should_update_history = true; params.gesture = NavigationGestureUnknown; params.is_post = false; - params.content_state = webkit_glue::CreateHistoryStateForURL(GURL(url)); + params.page_state = PageState::CreateFromURL(url); // This SHOULD generate a new entry. LoadCommittedDetails details; @@ -2093,7 +2093,7 @@ TEST_F(NavigationControllerTest, RestoreNavigate) { browser_context()); entry->SetPageID(0); entry->SetTitle(ASCIIToUTF16("Title")); - entry->SetContentState("state"); + entry->SetPageState(PageState::CreateFromEncodedData("state")); const base::Time timestamp = base::Time::Now(); entry->SetTimestamp(timestamp); entries.push_back(entry); @@ -2139,7 +2139,7 @@ TEST_F(NavigationControllerTest, RestoreNavigate) { params.should_update_history = false; params.gesture = NavigationGestureUser; params.is_post = false; - params.content_state = webkit_glue::CreateHistoryStateForURL(GURL(url)); + params.page_state = PageState::CreateFromURL(url); LoadCommittedDetails details; our_controller.RendererDidNavigate(params, &details); @@ -2172,7 +2172,7 @@ TEST_F(NavigationControllerTest, RestoreNavigateAfterFailure) { browser_context()); entry->SetPageID(0); entry->SetTitle(ASCIIToUTF16("Title")); - entry->SetContentState("state"); + entry->SetPageState(PageState::CreateFromEncodedData("state")); entries.push_back(entry); scoped_ptr<WebContentsImpl> our_contents(static_cast<WebContentsImpl*>( WebContents::Create(WebContents::CreateParams(browser_context())))); @@ -2225,7 +2225,7 @@ TEST_F(NavigationControllerTest, RestoreNavigateAfterFailure) { params.should_update_history = false; params.gesture = NavigationGestureUser; params.is_post = false; - params.content_state = webkit_glue::CreateHistoryStateForURL(GURL(url)); + params.page_state = PageState::CreateFromURL(url); LoadCommittedDetails details; our_controller.RendererDidNavigate(params, &details); @@ -2594,7 +2594,7 @@ TEST_F(NavigationControllerTest, SameSubframe) { params.should_update_history = false; params.gesture = NavigationGestureAuto; params.is_post = false; - params.content_state = webkit_glue::CreateHistoryStateForURL(GURL(subframe)); + params.page_state = PageState::CreateFromURL(subframe); LoadCommittedDetails details; EXPECT_FALSE(controller.RendererDidNavigate(params, &details)); @@ -2664,7 +2664,7 @@ TEST_F(NavigationControllerTest, SubframeWhilePending) { params.should_update_history = false; params.gesture = NavigationGestureAuto; params.is_post = false; - params.content_state = webkit_glue::CreateHistoryStateForURL(GURL(url1_sub)); + params.page_state = PageState::CreateFromURL(url1_sub); LoadCommittedDetails details; // This should return false meaning that nothing was actually updated. diff --git a/content/browser/web_contents/navigation_entry_impl.cc b/content/browser/web_contents/navigation_entry_impl.cc index b904acf703..23c90e9d9b 100644 --- a/content/browser/web_contents/navigation_entry_impl.cc +++ b/content/browser/web_contents/navigation_entry_impl.cc @@ -135,12 +135,12 @@ const string16& NavigationEntryImpl::GetTitle() const { return title_; } -void NavigationEntryImpl::SetContentState(const std::string& state) { - content_state_ = state; +void NavigationEntryImpl::SetPageState(const PageState& state) { + page_state_ = state; } -const std::string& NavigationEntryImpl::GetContentState() const { - return content_state_; +const PageState& NavigationEntryImpl::GetPageState() const { + return page_state_; } void NavigationEntryImpl::SetPageID(int page_id) { diff --git a/content/browser/web_contents/navigation_entry_impl.h b/content/browser/web_contents/navigation_entry_impl.h index c956867c15..96d7ac9e2b 100644 --- a/content/browser/web_contents/navigation_entry_impl.h +++ b/content/browser/web_contents/navigation_entry_impl.h @@ -11,6 +11,7 @@ #include "content/public/browser/favicon_status.h" #include "content/public/browser/global_request_id.h" #include "content/public/browser/navigation_entry.h" +#include "content/public/common/page_state.h" #include "content/public/common/ssl_status.h" namespace content { @@ -46,8 +47,8 @@ class CONTENT_EXPORT NavigationEntryImpl virtual const GURL& GetVirtualURL() const OVERRIDE; virtual void SetTitle(const string16& title) OVERRIDE; virtual const string16& GetTitle() const OVERRIDE; - virtual void SetContentState(const std::string& state) OVERRIDE; - virtual const std::string& GetContentState() const OVERRIDE; + virtual void SetPageState(const PageState& state) OVERRIDE; + virtual const PageState& GetPageState() const OVERRIDE; virtual void SetPageID(int page_id) OVERRIDE; virtual int32 GetPageID() const OVERRIDE; virtual const string16& GetTitleForDisplay( @@ -219,7 +220,7 @@ class CONTENT_EXPORT NavigationEntryImpl bool update_virtual_url_with_url_; string16 title_; FaviconStatus favicon_; - std::string content_state_; + PageState page_state_; int32 page_id_; SSLStatus ssl_; PageTransition transition_type_; diff --git a/content/browser/web_contents/navigation_entry_impl_unittest.cc b/content/browser/web_contents/navigation_entry_impl_unittest.cc index 8bc5de11ed..4b18aaad6e 100644 --- a/content/browser/web_contents/navigation_entry_impl_unittest.cc +++ b/content/browser/web_contents/navigation_entry_impl_unittest.cc @@ -142,10 +142,10 @@ TEST_F(NavigationEntryTest, NavigationEntryAccessors) { EXPECT_EQ(ASCIIToUTF16("title2"), entry2_->GetTitle()); // State - EXPECT_EQ(std::string(), entry1_->GetContentState()); - EXPECT_EQ(std::string(), entry2_->GetContentState()); - entry2_->SetContentState("state"); - EXPECT_EQ("state", entry2_->GetContentState()); + EXPECT_FALSE(entry1_->GetPageState().IsValid()); + EXPECT_FALSE(entry2_->GetPageState().IsValid()); + entry2_->SetPageState(PageState::CreateFromEncodedData("state")); + EXPECT_EQ("state", entry2_->GetPageState().ToEncodedData()); // Page ID EXPECT_EQ(-1, entry1_->GetPageID()); diff --git a/content/browser/web_contents/render_view_host_manager_unittest.cc b/content/browser/web_contents/render_view_host_manager_unittest.cc index c4fd94a163..0ad1f7fb92 100644 --- a/content/browser/web_contents/render_view_host_manager_unittest.cc +++ b/content/browser/web_contents/render_view_host_manager_unittest.cc @@ -19,6 +19,7 @@ #include "content/public/common/javascript_message_type.h" #include "content/public/common/page_transition_types.h" #include "content/public/common/url_constants.h" +#include "content/public/common/url_utils.h" #include "content/public/test/mock_render_process_host.h" #include "content/public/test/test_browser_context.h" #include "content/public/test/test_notification_tracker.h" @@ -26,7 +27,6 @@ #include "content/test/test_content_client.h" #include "content/test/test_web_contents.h" #include "testing/gtest/include/gtest/gtest.h" -#include "webkit/glue/glue_serialize.h" namespace content { namespace { @@ -725,7 +725,7 @@ TEST_F(RenderViewHostManagerTest, PageDoesBackAndReload) { params.gesture = NavigationGestureAuto; params.was_within_same_page = false; params.is_post = false; - params.content_state = webkit_glue::CreateHistoryStateForURL(GURL(kUrl2)); + params.page_state = PageState::CreateFromURL(kUrl2); contents()->DidNavigate(evil_rvh, params); // That should have cancelled the pending RVH, and the evil RVH should be the diff --git a/content/browser/web_contents/web_contents_drag_win.cc b/content/browser/web_contents/web_contents_drag_win.cc index 8174c97c17..9153808d98 100644 --- a/content/browser/web_contents/web_contents_drag_win.cc +++ b/content/browser/web_contents/web_contents_drag_win.cc @@ -28,7 +28,7 @@ #include "content/public/browser/web_drag_dest_delegate.h" #include "net/base/net_util.h" #include "third_party/skia/include/core/SkBitmap.h" -#include "ui/base/clipboard/clipboard_util_win.h" +#include "ui/base/clipboard/clipboard.h" #include "ui/base/clipboard/custom_data_helper.h" #include "ui/base/dragdrop/drag_utils.h" #include "ui/base/layout.h" @@ -338,8 +338,7 @@ bool WebContentsDragWin::DoDragging(const WebDropData& drop_data, if (!drop_data.custom_data.empty()) { Pickle pickle; ui::WriteCustomDataToPickle(drop_data.custom_data, &pickle); - data.SetPickledData(ui::ClipboardUtil::GetWebCustomDataFormat()->cfFormat, - pickle); + data.SetPickledData(ui::Clipboard::GetWebCustomDataFormatType(), pickle); } // Set drag image. diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 9cc3694d86..0f8b1df5ef 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc @@ -217,7 +217,7 @@ void MakeNavigateParams(const NavigationEntryImpl& entry, } params->referrer = entry.GetReferrer(); params->transition = entry.GetTransitionType(); - params->state = entry.GetContentState(); + params->page_state = entry.GetPageState(); params->navigation_type = GetNavigationType(controller.GetBrowserContext(), entry, reload_type); params->request_time = base::Time::Now(); @@ -284,6 +284,26 @@ WebContents* WebContents::FromRenderViewHost(const RenderViewHost* rvh) { return rvh->GetDelegate()->GetAsWebContents(); } +// WebContentsImpl::DestructionObserver ---------------------------------------- + +class WebContentsImpl::DestructionObserver : public WebContentsObserver { + public: + DestructionObserver(WebContentsImpl* owner, WebContents* watched_contents) + : WebContentsObserver(watched_contents), + owner_(owner) { + } + + // WebContentsObserver: + virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE { + owner_->OnWebContentsDestroyed(static_cast<WebContentsImpl*>(web_contents)); + } + + private: + WebContentsImpl* owner_; + + DISALLOW_COPY_AND_ASSIGN(DestructionObserver); +}; + // WebContentsImpl ------------------------------------------------------------- WebContentsImpl::WebContentsImpl( @@ -316,7 +336,7 @@ WebContentsImpl::WebContentsImpl( maximum_zoom_percent_(static_cast<int>(kMaximumZoomFactor * 100)), temporary_zoom_settings_(false), content_restrictions_(0), - color_chooser_(NULL), + color_chooser_identifier_(0), message_source_(NULL), fullscreen_widget_routing_id_(MSG_ROUTING_NONE) { } @@ -371,6 +391,9 @@ WebContentsImpl::~WebContentsImpl() { WebContentsImplDestroyed()); SetDelegate(NULL); + + STLDeleteContainerPairSecondPointers(destruction_observers_.begin(), + destruction_observers_.end()); } WebContentsImpl* WebContentsImpl::CreateWithOpener( @@ -507,14 +530,16 @@ WebPreferences WebContentsImpl::GetWebkitPrefs(RenderViewHost* rvh, command_line.HasSwitch(switches::kEnableExperimentalWebKitFeatures); prefs.css_shaders_enabled = command_line.HasSwitch(switches::kEnableCssShaders); - prefs.css_variables_enabled = - command_line.HasSwitch(switches::kEnableExperimentalWebKitFeatures); prefs.css_grid_layout_enabled = command_line.HasSwitch(switches::kEnableExperimentalWebKitFeatures); prefs.lazy_layout_enabled = command_line.HasSwitch(switches::kEnableExperimentalWebKitFeatures); prefs.threaded_html_parser = !command_line.HasSwitch(switches::kDisableThreadedHTMLParser); + prefs.experimental_websocket_enabled = + command_line.HasSwitch(switches::kEnableExperimentalWebSocket); + prefs.pinch_virtual_viewport_enabled = + command_line.HasSwitch(cc::switches::kEnablePinchVirtualViewport); #if defined(OS_ANDROID) prefs.user_gesture_required_for_media_playback = !command_line.HasSwitch( @@ -574,15 +599,12 @@ WebPreferences WebContentsImpl::GetWebkitPrefs(RenderViewHost* rvh, // pages (unless it's specifically allowed). if ((url.SchemeIs(chrome::kChromeUIScheme) || (url.SchemeIs(chrome::kAboutScheme) && - url.spec() != chrome::kAboutBlankURL)) && + url.spec() != kAboutBlankURL)) && !command_line.HasSwitch(switches::kAllowWebUICompositing)) { prefs.accelerated_compositing_enabled = false; prefs.accelerated_2d_canvas_enabled = false; } - prefs.apply_default_device_scale_factor_in_compositor = true; - prefs.apply_page_scale_factor_in_compositor = true; - prefs.fixed_position_creates_stacking_context = !command_line.HasSwitch( switches::kDisableFixedPositionCreatesStackingContext); @@ -663,6 +685,8 @@ bool WebContentsImpl::OnMessageReceived(RenderViewHost* render_view_host, IPC_MESSAGE_HANDLER(ViewHostMsg_RegisterProtocolHandler, OnRegisterProtocolHandler) IPC_MESSAGE_HANDLER(ViewHostMsg_Find_Reply, OnFindReply) + IPC_MESSAGE_HANDLER(ViewHostMsg_DidProgrammaticallyScroll, + OnDidProgrammaticallyScroll) IPC_MESSAGE_HANDLER(ViewHostMsg_CrashedPlugin, OnCrashedPlugin) IPC_MESSAGE_HANDLER(ViewHostMsg_AppCacheAccessed, OnAppCacheAccessed) IPC_MESSAGE_HANDLER(ViewHostMsg_OpenColorChooser, OnOpenColorChooser) @@ -719,11 +743,23 @@ BrowserContext* WebContentsImpl::GetBrowserContext() const { } const GURL& WebContentsImpl::GetURL() const { - // We may not have a navigation entry yet + // We may not have a navigation entry yet. NavigationEntry* entry = controller_.GetActiveEntry(); return entry ? entry->GetVirtualURL() : GURL::EmptyGURL(); } +const GURL& WebContentsImpl::GetActiveURL() const { + // We may not have a navigation entry yet. + NavigationEntry* entry = controller_.GetActiveEntry(); + return entry ? entry->GetVirtualURL() : GURL::EmptyGURL(); +} + +const GURL& WebContentsImpl::GetLastCommittedURL() const { + // We may not have a navigation entry yet. + NavigationEntry* entry = controller_.GetLastCommittedEntry(); + return entry ? entry->GetVirtualURL() : GURL::EmptyGURL(); +} + WebContentsDelegate* WebContentsImpl::GetDelegate() { return delegate_; } @@ -856,6 +892,8 @@ const std::string& WebContentsImpl::GetUserAgentOverride() const { void WebContentsImpl::SetParentNativeViewAccessible( gfx::NativeViewAccessible accessible_parent) { accessible_parent_ = accessible_parent; + if (GetRenderViewHost()) + GetRenderViewHostImpl()->SetParentNativeViewAccessible(accessible_parent); } #endif @@ -1106,9 +1144,6 @@ void WebContentsImpl::Observe(int type, const NotificationSource& source, const NotificationDetails& details) { switch (type) { - case NOTIFICATION_WEB_CONTENTS_DESTROYED: - OnWebContentsDestroyed(Source<WebContents>(source).ptr()); - break; case NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED: { RenderWidgetHost* host = Source<RenderWidgetHost>(source).ptr(); for (PendingWidgetViews::iterator i = pending_widget_views_.begin(); @@ -1158,10 +1193,8 @@ void WebContentsImpl::Init(const WebContents::CreateParams& params) { view_->CreateView(initial_size, params.context); // Listen for whether our opener gets destroyed. - if (opener_) { - registrar_.Add(this, NOTIFICATION_WEB_CONTENTS_DESTROYED, - Source<WebContents>(opener_)); - } + if (opener_) + AddDestructionObserver(opener_); registrar_.Add(this, NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED, @@ -1176,11 +1209,11 @@ void WebContentsImpl::Init(const WebContents::CreateParams& params) { #endif } -void WebContentsImpl::OnWebContentsDestroyed(WebContents* web_contents) { +void WebContentsImpl::OnWebContentsDestroyed(WebContentsImpl* web_contents) { + RemoveDestructionObserver(web_contents); + // Clear the opener if it has been closed. if (web_contents == opener_) { - registrar_.Remove(this, NOTIFICATION_WEB_CONTENTS_DESTROYED, - Source<WebContents>(opener_)); opener_ = NULL; return; } @@ -1191,13 +1224,27 @@ void WebContentsImpl::OnWebContentsDestroyed(WebContents* web_contents) { if (iter->second != web_contents) continue; pending_contents_.erase(iter); - registrar_.Remove(this, NOTIFICATION_WEB_CONTENTS_DESTROYED, - Source<WebContents>(web_contents)); return; } NOTREACHED(); } +void WebContentsImpl::AddDestructionObserver(WebContentsImpl* web_contents) { + if (!ContainsKey(destruction_observers_, web_contents)) { + destruction_observers_[web_contents] = + new DestructionObserver(this, web_contents); + } +} + +void WebContentsImpl::RemoveDestructionObserver(WebContentsImpl* web_contents) { + DestructionObservers::iterator iter = + destruction_observers_.find(web_contents); + if (iter != destruction_observers_.end()) { + delete destruction_observers_[web_contents]; + destruction_observers_.erase(iter); + } +} + void WebContentsImpl::AddObserver(WebContentsObserver* observer) { observers_.AddObserver(observer); } @@ -1406,8 +1453,7 @@ void WebContentsImpl::CreateNewWindow( // later. DCHECK_NE(MSG_ROUTING_NONE, route_id); pending_contents_[route_id] = new_contents; - registrar_.Add(this, NOTIFICATION_WEB_CONTENTS_DESTROYED, - Source<WebContents>(new_contents)); + AddDestructionObserver(new_contents); } if (delegate_) { @@ -1542,8 +1588,7 @@ WebContentsImpl* WebContentsImpl::GetCreatedWindow(int route_id) { WebContentsImpl* new_contents = iter->second; pending_contents_.erase(route_id); - registrar_.Remove(this, NOTIFICATION_WEB_CONTENTS_DESTROYED, - Source<WebContents>(new_contents)); + RemoveDestructionObserver(new_contents); // Don't initialize the guest WebContents immediately. if (new_contents->GetRenderProcessHost()->IsGuest()) @@ -1596,6 +1641,11 @@ void WebContentsImpl::RequestMediaAccessPermission( callback.Run(MediaStreamDevices(), scoped_ptr<MediaStreamUI>()); } +void WebContentsImpl::DidSendScreenRects(RenderWidgetHostImpl* rwh) { + if (browser_plugin_embedder_) + browser_plugin_embedder_->DidSendScreenRects(rwh); +} + void WebContentsImpl::UpdatePreferredSize(const gfx::Size& pref_size) { preferred_size_ = pref_size; if (delegate_) @@ -1935,11 +1985,11 @@ void WebContentsImpl::ViewSource() { } void WebContentsImpl::ViewFrameSource(const GURL& url, - const std::string& content_state) { + const PageState& page_state) { if (!delegate_) return; - delegate_->ViewSourceForFrame(this, url, content_state); + delegate_->ViewSourceForFrame(this, url, page_state); } int WebContentsImpl::GetMinimumZoomPercent() const { @@ -1967,17 +2017,16 @@ bool WebContentsImpl::HasOpener() const { return opener_ != NULL; } -void WebContentsImpl::DidChooseColorInColorChooser(int color_chooser_id, - SkColor color) { +void WebContentsImpl::DidChooseColorInColorChooser(SkColor color) { Send(new ViewMsg_DidChooseColorResponse( - GetRoutingID(), color_chooser_id, color)); + GetRoutingID(), color_chooser_identifier_, color)); } -void WebContentsImpl::DidEndColorChooser(int color_chooser_id) { - Send(new ViewMsg_DidEndColorChooser(GetRoutingID(), color_chooser_id)); - if (delegate_) - delegate_->DidEndColorChooser(); - color_chooser_ = NULL; +void WebContentsImpl::DidEndColorChooser() { + Send(new ViewMsg_DidEndColorChooser(GetRoutingID(), + color_chooser_identifier_)); + color_chooser_.reset(); + color_chooser_identifier_ = 0; } int WebContentsImpl::DownloadImage(const GURL& url, @@ -1992,7 +2041,7 @@ int WebContentsImpl::DownloadImage(const GURL& url, bool WebContentsImpl::FocusLocationBarByDefault() { NavigationEntry* entry = controller_.GetActiveEntry(); - if (entry && entry->GetURL() == GURL(chrome::kAboutBlankURL)) + if (entry && entry->GetURL() == GURL(kAboutBlankURL)) return true; return delegate_ && delegate_->ShouldFocusLocationBarByDefault(this); } @@ -2009,7 +2058,7 @@ void WebContentsImpl::DidStartProvisionalLoadForFrame( bool is_main_frame, const GURL& url) { bool is_error_page = (url.spec() == kUnreachableWebDataURL); - bool is_iframe_srcdoc = (url.spec() == chrome::kAboutSrcDocURL); + bool is_iframe_srcdoc = (url.spec() == kAboutSrcDocURL); GURL validated_url(url); RenderProcessHost* render_process_host = render_view_host->GetProcess(); @@ -2289,6 +2338,12 @@ void WebContentsImpl::OnFindReply(int request_id, } } +void WebContentsImpl::OnDidProgrammaticallyScroll( + const gfx::Vector2d& scroll_point) { + if (delegate_) + delegate_->DidProgrammaticallyScroll(this, scroll_point); +} + #if defined(OS_ANDROID) void WebContentsImpl::OnFindMatchRectsReply( int version, @@ -2323,20 +2378,23 @@ void WebContentsImpl::OnAppCacheAccessed(const GURL& manifest_url, void WebContentsImpl::OnOpenColorChooser(int color_chooser_id, SkColor color) { - color_chooser_ = delegate_ ? - delegate_->OpenColorChooser(this, color_chooser_id, color) : NULL; + ColorChooser* new_color_chooser = delegate_->OpenColorChooser(this, color); + if (color_chooser_ == new_color_chooser) + return; + color_chooser_.reset(new_color_chooser); + color_chooser_identifier_ = color_chooser_id; } void WebContentsImpl::OnEndColorChooser(int color_chooser_id) { if (color_chooser_ && - color_chooser_id == color_chooser_->identifier()) + color_chooser_id == color_chooser_identifier_) color_chooser_->End(); } void WebContentsImpl::OnSetSelectedColorInColorChooser(int color_chooser_id, SkColor color) { if (color_chooser_ && - color_chooser_id == color_chooser_->identifier()) + color_chooser_id == color_chooser_identifier_) color_chooser_->SetSelectedColor(color); } @@ -2397,6 +2455,7 @@ void WebContentsImpl::OnBrowserPluginMessage(const IPC::Message& message) { void WebContentsImpl::OnDidDownloadImage( int id, + int http_status_code, const GURL& image_url, int requested_size, const std::vector<SkBitmap>& bitmaps) { @@ -2407,7 +2466,7 @@ void WebContentsImpl::OnDidDownloadImage( return; } if (!iter->second.is_null()) { - iter->second.Run(id, image_url, requested_size, bitmaps); + iter->second.Run(id, http_status_code, image_url, requested_size, bitmaps); } image_download_map_.erase(id); } @@ -2779,7 +2838,7 @@ void WebContentsImpl::DidNavigate( // this is for about:blank. In that case, the SiteInstance can still be // considered unused until a navigation to a real page. if (!static_cast<SiteInstanceImpl*>(GetSiteInstance())->HasSite() && - params.url != GURL(chrome::kAboutBlankURL)) { + params.url != GURL(kAboutBlankURL)) { static_cast<SiteInstanceImpl*>(GetSiteInstance())->SetSite(params.url); } @@ -2843,7 +2902,7 @@ void WebContentsImpl::DidNavigate( void WebContentsImpl::UpdateState(RenderViewHost* rvh, int32 page_id, - const std::string& state) { + const PageState& page_state) { // Ensure that this state update comes from either the active RVH or one of // the swapped out RVHs. We don't expect to hear from any other RVHs. DCHECK(rvh == GetRenderViewHost() || render_manager_.IsOnSwappedOutList(rvh)); @@ -2860,9 +2919,9 @@ void WebContentsImpl::UpdateState(RenderViewHost* rvh, return; NavigationEntry* entry = controller_.GetEntryAtIndex(entry_index); - if (state == entry->GetContentState()) + if (page_state == entry->GetPageState()) return; // Nothing to update. - entry->SetContentState(state); + entry->SetPageState(page_state); controller_.NotifyEntryChanged(entry, entry_index); } @@ -2990,8 +3049,7 @@ void WebContentsImpl::DidDisownOpener(RenderViewHost* rvh) { if (opener_) { // Clear our opener so that future cross-process navigations don't have an // opener assigned. - registrar_.Remove(this, NOTIFICATION_WEB_CONTENTS_DESTROYED, - Source<WebContents>(opener_)); + RemoveDestructionObserver(opener_); opener_ = NULL; } diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index a7a408b6e6..2af13f82f0 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h @@ -29,6 +29,7 @@ #include "third_party/WebKit/Source/WebKit/chromium/public/WebDragOperation.h" #include "ui/gfx/rect_f.h" #include "ui/gfx/size.h" +#include "ui/gfx/vector2d.h" #include "webkit/glue/resource_type.h" struct BrowserPluginHostMsg_ResizeGuest_Params; @@ -275,16 +276,15 @@ class CONTENT_EXPORT WebContentsImpl bool* enable_decrement) const OVERRIDE; virtual void ViewSource() OVERRIDE; virtual void ViewFrameSource(const GURL& url, - const std::string& content_state) OVERRIDE; + const PageState& page_state) OVERRIDE; virtual int GetMinimumZoomPercent() const OVERRIDE; virtual int GetMaximumZoomPercent() const OVERRIDE; virtual gfx::Size GetPreferredSize() const OVERRIDE; virtual int GetContentRestrictions() const OVERRIDE; virtual bool GotResponseToLockMouseRequest(bool allowed) OVERRIDE; virtual bool HasOpener() const OVERRIDE; - virtual void DidChooseColorInColorChooser(int color_chooser_id, - SkColor color) OVERRIDE; - virtual void DidEndColorChooser(int color_chooser_id) OVERRIDE; + virtual void DidChooseColorInColorChooser(SkColor color) OVERRIDE; + virtual void DidEndColorChooser() OVERRIDE; virtual int DownloadImage(const GURL& url, bool is_favicon, int image_size, @@ -304,6 +304,8 @@ class CONTENT_EXPORT WebContentsImpl virtual bool OnMessageReceived(RenderViewHost* render_view_host, const IPC::Message& message) OVERRIDE; virtual const GURL& GetURL() const OVERRIDE; + virtual const GURL& GetActiveURL() const OVERRIDE; + virtual const GURL& GetLastCommittedURL() const OVERRIDE; virtual WebContents* GetAsWebContents() OVERRIDE; virtual gfx::Rect GetRootWindowResizerRect() const OVERRIDE; virtual void RenderViewCreated(RenderViewHost* render_view_host) OVERRIDE; @@ -332,7 +334,7 @@ class CONTENT_EXPORT WebContentsImpl const ViewHostMsg_FrameNavigate_Params& params) OVERRIDE; virtual void UpdateState(RenderViewHost* render_view_host, int32 page_id, - const std::string& state) OVERRIDE; + const PageState& page_state) OVERRIDE; virtual void UpdateTitle(RenderViewHost* render_view_host, int32 page_id, const string16& title, @@ -448,6 +450,7 @@ class CONTENT_EXPORT WebContentsImpl const NativeWebKeyboardEvent& event) OVERRIDE; virtual bool PreHandleWheelEvent( const WebKit::WebMouseWheelEvent& event) OVERRIDE; + virtual void DidSendScreenRects(RenderWidgetHostImpl* rwh) OVERRIDE; #if defined(OS_WIN) && defined(USE_AURA) virtual gfx::NativeViewAccessible GetParentNativeViewAccessible() OVERRIDE; #endif @@ -504,6 +507,8 @@ class CONTENT_EXPORT WebContentsImpl // TODO(brettw) TestWebContents shouldn't exist! friend class TestWebContents; + class DestructionObserver; + // See WebContents::Create for a description of these parameters. WebContentsImpl(BrowserContext* browser_context, WebContentsImpl* opener); @@ -516,7 +521,15 @@ class CONTENT_EXPORT WebContentsImpl void RemoveObserver(WebContentsObserver* observer); // Clears this tab's opener if it has been closed. - void OnWebContentsDestroyed(WebContents* web_contents); + void OnWebContentsDestroyed(WebContentsImpl* web_contents); + + // Creates and adds to the map a destruction observer watching |web_contents|. + // No-op if such an observer already exists. + void AddDestructionObserver(WebContentsImpl* web_contents); + + // Deletes and removes from the map a destruction observer + // watching |web_contents|. No-op if there is no such observer. + void RemoveDestructionObserver(WebContentsImpl* web_contents); // Callback function when showing JS dialogs. void OnDialogClosed(RenderViewHost* rvh, @@ -564,6 +577,7 @@ class CONTENT_EXPORT WebContentsImpl const gfx::Rect& selection_rect, int active_match_ordinal, bool final_update); + void OnDidProgrammaticallyScroll(const gfx::Vector2d& scroll_point); #if defined(OS_ANDROID) void OnFindMatchRectsReply(int version, const std::vector<gfx::RectF>& rects, @@ -589,6 +603,7 @@ class CONTENT_EXPORT WebContentsImpl const base::FilePath& plugin_path); void OnBrowserPluginMessage(const IPC::Message& message); void OnDidDownloadImage(int id, + int http_status_code, const GURL& image_url, int requested_size, const std::vector<SkBitmap>& bitmaps); @@ -737,6 +752,9 @@ class CONTENT_EXPORT WebContentsImpl typedef std::map<int, RenderWidgetHostView*> PendingWidgetViews; PendingWidgetViews pending_widget_views_; + typedef std::map<WebContentsImpl*, DestructionObserver*> DestructionObservers; + DestructionObservers destruction_observers_; + // A list of observers notified when page state changes. Weak references. // This MUST be listed above render_manager_ since at destruction time the // latter might cause RenderViewHost's destructor to call us and we might use @@ -882,7 +900,16 @@ class CONTENT_EXPORT WebContentsImpl #endif // Color chooser that was opened by this tab. - ColorChooser* color_chooser_; + scoped_ptr<ColorChooser> color_chooser_; + + // A unique identifier for the current color chooser. Identifiers are unique + // across a renderer process. This avoids race conditions in synchronizing + // the browser and renderer processes. For example, if a renderer closes one + // chooser and opens another, and simultaneously the user picks a color in the + // first chooser, the IDs can be used to drop the "chose a color" message + // rather than erroneously tell the renderer that the user picked a color in + // the second chooser. + int color_chooser_identifier_; // Manages the embedder state for browser plugins, if this WebContents is an // embedder; NULL otherwise. diff --git a/content/browser/web_contents/web_contents_impl_browsertest.cc b/content/browser/web_contents/web_contents_impl_browsertest.cc index 66e085727b..000da0e798 100644 --- a/content/browser/web_contents/web_contents_impl_browsertest.cc +++ b/content/browser/web_contents/web_contents_impl_browsertest.cc @@ -10,12 +10,13 @@ #include "content/public/browser/notification_details.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_types.h" +#include "content/public/common/content_paths.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/test_utils.h" #include "content/shell/shell.h" #include "content/test/content_browser_test.h" #include "content/test/content_browser_test_utils.h" -#include "net/test/spawned_test_server/spawned_test_server.h" +#include "net/test/embedded_test_server/embedded_test_server.h" namespace content { @@ -85,14 +86,14 @@ class NavigateOnCommitObserver : public WindowedNotificationObserver { // Test that DidStopLoading includes the correct URL in the details. IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, DidStopLoadingDetails) { - ASSERT_TRUE(test_server()->Start()); + ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); LoadStopNotificationObserver load_observer( &shell()->web_contents()->GetController()); - NavigateToURL(shell(), test_server()->GetURL("files/title1.html")); + NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html")); load_observer.Wait(); - EXPECT_EQ("/files/title1.html", load_observer.url_.path()); + EXPECT_EQ("/title1.html", load_observer.url_.path()); EXPECT_EQ(0, load_observer.session_index_); EXPECT_EQ(&shell()->web_contents()->GetController(), load_observer.controller_); @@ -102,7 +103,7 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, DidStopLoadingDetails) { // pending entry is present. IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, DidStopLoadingDetailsWithPending) { - ASSERT_TRUE(test_server()->Start()); + ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); // Listen for the first load to stop. LoadStopNotificationObserver load_observer( @@ -111,12 +112,12 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, // We will hear a DidStopLoading from the first load as the new load // is started. NavigateOnCommitObserver commit_observer( - shell(), test_server()->GetURL("files/title2.html")); - NavigateToURL(shell(), test_server()->GetURL("files/title1.html")); + shell(), embedded_test_server()->GetURL("/title2.html")); + NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html")); commit_observer.Wait(); load_observer.Wait(); - EXPECT_EQ("/files/title1.html", load_observer.url_.path()); + EXPECT_EQ("/title1.html", load_observer.url_.path()); EXPECT_EQ(0, load_observer.session_index_); EXPECT_EQ(&shell()->web_contents()->GetController(), load_observer.controller_); @@ -125,9 +126,10 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, // Test that the browser receives the proper frame attach/detach messages from // the renderer and builds proper frame tree. IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, FrameTree) { - ASSERT_TRUE(test_server()->Start()); + ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); - NavigateToURL(shell(), test_server()->GetURL("files/frame_tree/top.html")); + NavigateToURL(shell(), + embedded_test_server()->GetURL("/frame_tree/top.html")); WebContentsImpl* wc = static_cast<WebContentsImpl*>(shell()->web_contents()); RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>( @@ -152,7 +154,7 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, FrameTree) { // Navigate to about:blank, which should leave only the root node of the frame // tree in the browser process. - NavigateToURL(shell(), test_server()->GetURL("files/title1.html")); + NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html")); root = wc->GetFrameTreeRootForTesting(); EXPECT_EQ(0UL, root->child_count()); diff --git a/content/browser/web_contents/web_contents_impl_unittest.cc b/content/browser/web_contents/web_contents_impl_unittest.cc index 6d7908854e..63ae5f5c28 100644 --- a/content/browser/web_contents/web_contents_impl_unittest.cc +++ b/content/browser/web_contents/web_contents_impl_unittest.cc @@ -30,7 +30,6 @@ #include "content/test/test_content_client.h" #include "content/test/test_web_contents.h" #include "testing/gtest/include/gtest/gtest.h" -#include "webkit/glue/webkit_glue.h" namespace content { namespace { @@ -297,8 +296,7 @@ TEST_F(WebContentsImplTest, UpdateTitle) { NavigationControllerImpl& cont = static_cast<NavigationControllerImpl&>(controller()); ViewHostMsg_FrameNavigate_Params params; - InitNavigateParams(¶ms, 0, GURL(chrome::kAboutBlankURL), - PAGE_TRANSITION_TYPED); + InitNavigateParams(¶ms, 0, GURL(kAboutBlankURL), PAGE_TRANSITION_TYPED); LoadCommittedDetails details; cont.RendererDidNavigate(params, &details); @@ -414,12 +412,16 @@ TEST_F(WebContentsImplTest, CrossSiteBoundaries) { EXPECT_FALSE(contents()->cross_navigation_pending()); EXPECT_EQ(orig_rvh, contents()->GetRenderViewHost()); + EXPECT_EQ(url, contents()->GetLastCommittedURL()); + EXPECT_EQ(url, contents()->GetActiveURL()); // Navigate to new site const GURL url2("http://www.yahoo.com"); controller().LoadURL( url2, Referrer(), PAGE_TRANSITION_TYPED, std::string()); EXPECT_TRUE(contents()->cross_navigation_pending()); + EXPECT_EQ(url, contents()->GetLastCommittedURL()); + EXPECT_EQ(url2, contents()->GetActiveURL()); TestRenderViewHost* pending_rvh = static_cast<TestRenderViewHost*>(contents()->GetPendingRenderViewHost()); int pending_rvh_delete_count = 0; @@ -437,6 +439,8 @@ TEST_F(WebContentsImplTest, CrossSiteBoundaries) { EXPECT_FALSE(contents()->cross_navigation_pending()); EXPECT_EQ(pending_rvh, contents()->GetRenderViewHost()); + EXPECT_EQ(url2, contents()->GetLastCommittedURL()); + EXPECT_EQ(url2, contents()->GetActiveURL()); EXPECT_NE(instance1, instance2); EXPECT_TRUE(contents()->GetPendingRenderViewHost() == NULL); // We keep the original RVH around, swapped out. @@ -1018,7 +1022,7 @@ TEST_F(WebContentsImplTest, CrossSiteNavigationCanceled) { EXPECT_TRUE(contents()->GetPendingRenderViewHost() == NULL); } -// Test that NavigationEntries have the correct content state after going +// Test that NavigationEntries have the correct page state after going // forward and back. Prevents regression for bug 1116137. TEST_F(WebContentsImplTest, NavigationEntryContentState) { TestRenderViewHost* orig_rvh = test_rvh(); @@ -1029,30 +1033,30 @@ TEST_F(WebContentsImplTest, NavigationEntryContentState) { NavigationEntry* entry = controller().GetLastCommittedEntry(); EXPECT_TRUE(entry == NULL); - // Committed entry should have content state after DidNavigate. + // Committed entry should have page state after DidNavigate. contents()->TestDidNavigate(orig_rvh, 1, url, PAGE_TRANSITION_TYPED); entry = controller().GetLastCommittedEntry(); - EXPECT_FALSE(entry->GetContentState().empty()); + EXPECT_TRUE(entry->GetPageState().IsValid()); // Navigate to same site. const GURL url2("http://images.google.com"); controller().LoadURL(url2, Referrer(), PAGE_TRANSITION_TYPED, std::string()); entry = controller().GetLastCommittedEntry(); - EXPECT_FALSE(entry->GetContentState().empty()); + EXPECT_TRUE(entry->GetPageState().IsValid()); - // Committed entry should have content state after DidNavigate. + // Committed entry should have page state after DidNavigate. contents()->TestDidNavigate(orig_rvh, 2, url2, PAGE_TRANSITION_TYPED); entry = controller().GetLastCommittedEntry(); - EXPECT_FALSE(entry->GetContentState().empty()); + EXPECT_TRUE(entry->GetPageState().IsValid()); - // Now go back. Committed entry should still have content state. + // Now go back. Committed entry should still have page state. controller().GoBack(); contents()->TestDidNavigate(orig_rvh, 1, url, PAGE_TRANSITION_TYPED); entry = controller().GetLastCommittedEntry(); - EXPECT_FALSE(entry->GetContentState().empty()); + EXPECT_TRUE(entry->GetPageState().IsValid()); } -// Test that NavigationEntries have the correct content state and SiteInstance +// Test that NavigationEntries have the correct page state and SiteInstance // state after opening a new window to about:blank. Prevents regression for // bugs b/1116137 and http://crbug.com/111975. TEST_F(WebContentsImplTest, NavigationEntryContentStateNewWindow) { @@ -1060,13 +1064,13 @@ TEST_F(WebContentsImplTest, NavigationEntryContentStateNewWindow) { // When opening a new window, it is navigated to about:blank internally. // Currently, this results in two DidNavigate events. - const GURL url(chrome::kAboutBlankURL); + const GURL url(kAboutBlankURL); contents()->TestDidNavigate(orig_rvh, 1, url, PAGE_TRANSITION_TYPED); contents()->TestDidNavigate(orig_rvh, 1, url, PAGE_TRANSITION_TYPED); - // Should have a content state here. + // Should have a page state here. NavigationEntry* entry = controller().GetLastCommittedEntry(); - EXPECT_FALSE(entry->GetContentState().empty()); + EXPECT_TRUE(entry->GetPageState().IsValid()); // The SiteInstance should be available for other navigations to use. NavigationEntryImpl* entry_impl = diff --git a/content/browser/web_contents/web_contents_view_android.cc b/content/browser/web_contents/web_contents_view_android.cc index bd60290396..6f7baf337d 100644 --- a/content/browser/web_contents/web_contents_view_android.cc +++ b/content/browser/web_contents/web_contents_view_android.cc @@ -6,13 +6,13 @@ #include "base/logging.h" #include "content/browser/android/content_view_core_impl.h" -#include "content/browser/android/media_player_manager_impl.h" #include "content/browser/renderer_host/render_widget_host_view_android.h" #include "content/browser/renderer_host/render_view_host_factory.h" #include "content/browser/renderer_host/render_view_host_impl.h" #include "content/browser/web_contents/interstitial_page_impl.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/public/browser/web_contents_delegate.h" +#include "media/base/android/media_player_manager.h" namespace content { WebContentsViewPort* CreateWebContentsView( diff --git a/content/browser/web_contents/web_contents_view_aura.cc b/content/browser/web_contents/web_contents_view_aura.cc index 51b304d781..544351b8e4 100644 --- a/content/browser/web_contents/web_contents_view_aura.cc +++ b/content/browser/web_contents/web_contents_view_aura.cc @@ -39,6 +39,7 @@ #include "ui/aura/root_window_observer.h" #include "ui/aura/window.h" #include "ui/aura/window_observer.h" +#include "ui/base/clipboard/clipboard.h" #include "ui/base/clipboard/custom_data_helper.h" #include "ui/base/dragdrop/drag_drop_types.h" #include "ui/base/dragdrop/drag_utils.h" @@ -55,10 +56,6 @@ #include "ui/gfx/screen.h" #include "webkit/glue/webdropdata.h" -#if defined(OS_WIN) -#include "ui/base/clipboard/clipboard_util_win.h" -#endif - namespace content { WebContentsViewPort* CreateWebContentsView( WebContentsImpl* web_contents, @@ -189,7 +186,7 @@ class WebDragSourceAura : public base::MessageLoopForUI::Observer, rvh = contents_->GetRenderViewHost(); if (rvh) { gfx::Point screen_loc_in_pixel = ui::EventLocationFromNative(event); - gfx::Point screen_loc = ConvertPointToDIP(rvh->GetView(), + gfx::Point screen_loc = ConvertViewPointToDIP(rvh->GetView(), screen_loc_in_pixel); gfx::Point client_loc = screen_loc; aura::Window* window = rvh->GetView()->GetNativeView(); @@ -254,13 +251,8 @@ void PrepareDragData(const WebDropData& drop_data, if (!drop_data.custom_data.empty()) { Pickle pickle; ui::WriteCustomDataToPickle(drop_data.custom_data, &pickle); -#if defined(OS_WIN) - provider->SetPickledData( - ui::ClipboardUtil::GetWebCustomDataFormat()->cfFormat, pickle); -#else provider->SetPickledData(ui::Clipboard::GetWebCustomDataFormatType(), pickle); -#endif } } @@ -300,15 +292,9 @@ void PrepareWebDropData(WebDropData* drop_data, } Pickle pickle; -#if defined(OS_WIN) - if (data.GetPickledData(ui::ClipboardUtil::GetWebCustomDataFormat()->cfFormat, - &pickle)) -#else - if (data.GetPickledData(ui::Clipboard::GetWebCustomDataFormatType(), - &pickle)) -#endif - ui::ReadCustomDataIntoMap(pickle.data(), pickle.size(), - &drop_data->custom_data); + if (data.GetPickledData(ui::Clipboard::GetWebCustomDataFormatType(), &pickle)) + ui::ReadCustomDataIntoMap( + pickle.data(), pickle.size(), &drop_data->custom_data); } // Utilities to convert between WebKit::WebDragOperationsMask and diff --git a/content/browser/web_contents/web_contents_view_gtk.cc b/content/browser/web_contents/web_contents_view_gtk.cc index 9cb9212787..f263c5f3f1 100644 --- a/content/browser/web_contents/web_contents_view_gtk.cc +++ b/content/browser/web_contents/web_contents_view_gtk.cc @@ -223,12 +223,17 @@ RenderWidgetHostView* WebContentsViewGtk::CreateViewForWidget( GDK_POINTER_MOTION_MASK); InsertIntoContentArea(content_view); - // We don't want to change any state in this class for swapped out RVHs - // because they will not be visible at this time. if (render_widget_host->IsRenderView()) { RenderViewHost* rvh = RenderViewHost::From(render_widget_host); - if (!static_cast<RenderViewHostImpl*>(rvh)->is_swapped_out()) + // If |rvh| is already the current render view host for the web contents, we + // need to initialize |drag_dest_| for drags to be properly handled. + // Otherwise, |drag_dest_| will be updated in RenderViewSwappedIn. The + // reason we can't simply check that this isn't a swapped-out view is + // because there are navigations that create non-swapped-out views that may + // never be displayed, e.g. a navigation that becomes a download. + if (rvh == web_contents_->GetRenderViewHost()) { UpdateDragDest(rvh); + } } return view; diff --git a/content/browser/webui/web_ui_controller_factory_registry.cc b/content/browser/webui/web_ui_controller_factory_registry.cc index 5e7bd63ae5..32220acd99 100644 --- a/content/browser/webui/web_ui_controller_factory_registry.cc +++ b/content/browser/webui/web_ui_controller_factory_registry.cc @@ -85,7 +85,7 @@ bool WebUIControllerFactoryRegistry::IsURLAcceptableForWebUI( url.SchemeIs(chrome::kJavaScriptScheme) || // It's possible to load about:blank in a Web UI renderer. // See http://crbug.com/42547 - url.spec() == chrome::kAboutBlankURL || + url.spec() == kAboutBlankURL || // Chrome URLs crash, kill, hang, and shorthang are allowed. url == GURL(kChromeUICrashURL) || url == GURL(kChromeUIKillURL) || diff --git a/content/browser/worker_host/test/worker_browsertest.cc b/content/browser/worker_host/test/worker_browsertest.cc index 54bfab3383..ddbf17a468 100644 --- a/content/browser/worker_host/test/worker_browsertest.cc +++ b/content/browser/worker_host/test/worker_browsertest.cc @@ -196,7 +196,9 @@ class WorkerXHRHttpLayoutTest : public InProcessBrowserLayoutTest { }; // TestRunner appears to be broken on Windows. See http://crbug.com/177798 -#if defined(OS_WIN) +// WorkerXHRHttpLayoutTest.Tests also crash under AddressSanitizer on Linux. +// See http://crbug.com/242447. +#if defined(OS_WIN) || defined(ADDRESS_SANITIZER) #define MAYBE_Tests DISABLED_Tests #else #define MAYBE_Tests Tests diff --git a/content/browser/worker_host/worker_process_host.cc b/content/browser/worker_host/worker_process_host.cc index b818b9d1b8..c2008040a5 100644 --- a/content/browser/worker_host/worker_process_host.cc +++ b/content/browser/worker_host/worker_process_host.cc @@ -48,8 +48,8 @@ #include "net/base/registry_controlled_domains/registry_controlled_domain.h" #include "net/url_request/url_request_context_getter.h" #include "ui/base/ui_base_switches.h" -#include "webkit/fileapi/file_system_context.h" -#include "webkit/fileapi/sandbox_mount_point_provider.h" +#include "webkit/browser/fileapi/file_system_context.h" +#include "webkit/browser/fileapi/sandbox_mount_point_provider.h" #include "webkit/glue/resource_type.h" #if defined(OS_WIN) diff --git a/content/browser/worker_host/worker_storage_partition.cc b/content/browser/worker_host/worker_storage_partition.cc index 994f7297c3..21f219677a 100644 --- a/content/browser/worker_host/worker_storage_partition.cc +++ b/content/browser/worker_host/worker_storage_partition.cc @@ -9,8 +9,8 @@ #include "content/browser/appcache/chrome_appcache_service.h" #include "content/browser/indexed_db/indexed_db_context_impl.h" #include "net/url_request/url_request_context_getter.h" -#include "webkit/database/database_tracker.h" -#include "webkit/fileapi/file_system_context.h" +#include "webkit/browser/database/database_tracker.h" +#include "webkit/browser/fileapi/file_system_context.h" #include "webkit/quota/quota_manager.h" namespace content { |