diff options
author | Zeno Albisser <zeno.albisser@digia.com> | 2013-11-21 14:09:57 +0100 |
---|---|---|
committer | Andras Becsi <andras.becsi@digia.com> | 2013-11-29 15:14:36 +0100 |
commit | eb32ba6f51d0c21d58cd7d89785285ff8fa64624 (patch) | |
tree | 2c7c940e1dbee81b89d935626110816b494aa32c /chromium/content | |
parent | 9427c1a0222ebd67efef1a2c7990a0fa5c9aac84 (diff) | |
download | qtwebengine-chromium-eb32ba6f51d0c21d58cd7d89785285ff8fa64624.tar.gz |
Update chromium to branch 1599.
Change-Id: I04e775a946a208bb4500d3b722bcb05c82b9d7cb
Reviewed-by: Andras Becsi <andras.becsi@digia.com>
Diffstat (limited to 'chromium/content')
205 files changed, 2221 insertions, 3966 deletions
diff --git a/chromium/content/browser/accessibility/browser_accessibility_manager_android.cc b/chromium/content/browser/accessibility/browser_accessibility_manager_android.cc index e14aa0bb977..2da686af934 100644 --- a/chromium/content/browser/accessibility/browser_accessibility_manager_android.cc +++ b/chromium/content/browser/accessibility/browser_accessibility_manager_android.cc @@ -90,6 +90,12 @@ void BrowserAccessibilityManagerAndroid::NotifyAccessibilityEvent( if (obj.is_null()) return; + // Always send AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED to notify + // the Android system that the accessibility hierarchy rooted at this + // node has changed. + Java_BrowserAccessibilityManager_handleContentChanged( + env, obj.obj(), node->renderer_id()); + switch (type) { case AccessibilityNotificationLoadComplete: Java_BrowserAccessibilityManager_handlePageLoaded( @@ -131,9 +137,6 @@ void BrowserAccessibilityManagerAndroid::NotifyAccessibilityEvent( if (node->IsEditableText()) { Java_BrowserAccessibilityManager_handleEditableTextChanged( env, obj.obj(), node->renderer_id()); - } else { - Java_BrowserAccessibilityManager_handleContentChanged( - env, obj.obj(), node->renderer_id()); } break; default: diff --git a/chromium/content/browser/android/content_view_core_impl.cc b/chromium/content/browser/android/content_view_core_impl.cc index 80fe628dd02..33b3f068d2a 100644 --- a/chromium/content/browser/android/content_view_core_impl.cc +++ b/chromium/content/browser/android/content_view_core_impl.cc @@ -350,17 +350,17 @@ void ContentViewCoreImpl::OnTabCrashed() { return; Java_ContentViewCore_resetVSyncNotification(env, obj.obj()); - // If |tab_crashed_| is already true, just return. e.g. if two tabs share the - // render process, this will be called for each tab when the render process - // crashed. If user reload one tab, a new render process is created. It can be - // shared by the other tab. But if user closes the tab before reload the other + // Note that we might reach this place multiple times while the + // ContentViewCore remains crashed. E.g. if two tabs share the render process + // and the process crashes, this will be called for each tab. If the user + // reload one tab, a new render process is created and it can be shared by the + // other tab. But if user closes the reloaded tab before reloading the other // tab, the new render process will be shut down. This will trigger the other // tab's OnTabCrashed() called again as two tabs share the same - // BrowserRenderProcessHost. - if (tab_crashed_) - return; + // BrowserRenderProcessHost. The Java side will distinguish this case using + // tab_crashed_ passed below. + Java_ContentViewCore_onTabCrash(env, obj.obj(), tab_crashed_); tab_crashed_ = true; - Java_ContentViewCore_onTabCrash(env, obj.obj()); } // All positions and sizes are in CSS pixels. @@ -800,12 +800,7 @@ jint ContentViewCoreImpl::GetCurrentRenderProcessId(JNIEnv* env, jobject obj) { ScopedJavaLocalRef<jstring> ContentViewCoreImpl::GetURL( JNIEnv* env, jobject) const { - // The current users of the Java API expect to use the active entry - // rather than the visible entry, which is exposed by WebContents::GetURL. - content::NavigationEntry* entry = - web_contents_->GetController().GetActiveEntry(); - GURL url = entry ? entry->GetVirtualURL() : GURL::EmptyGURL(); - return ConvertUTF8ToJavaString(env, url.spec()); + return ConvertUTF8ToJavaString(env, GetWebContents()->GetURL().spec()); } ScopedJavaLocalRef<jstring> ContentViewCoreImpl::GetTitle( @@ -1431,7 +1426,7 @@ void ContentViewCoreImpl::GetDirectedNavigationHistory(JNIEnv* env, ScopedJavaLocalRef<jstring> ContentViewCoreImpl::GetOriginalUrlForActiveNavigationEntry(JNIEnv* env, jobject obj) { - NavigationEntry* entry = web_contents_->GetController().GetActiveEntry(); + NavigationEntry* entry = web_contents_->GetController().GetVisibleEntry(); if (entry == NULL) return ScopedJavaLocalRef<jstring>(env, NULL); return ConvertUTF8ToJavaString(env, entry->GetOriginalRequestURL().spec()); @@ -1472,14 +1467,22 @@ void JavaScriptResultCallback(const ScopedJavaGlobalRef<jobject>& callback, void ContentViewCoreImpl::EvaluateJavaScript(JNIEnv* env, jobject obj, jstring script, - jobject callback) { - RenderViewHost* host = web_contents_->GetRenderViewHost(); - DCHECK(host); + jobject callback, + jboolean start_renderer) { + RenderViewHost* rvh = web_contents_->GetRenderViewHost(); + DCHECK(rvh); + + if (start_renderer && !rvh->IsRenderViewLive()) { + if (!web_contents_->CreateRenderViewForInitialEmptyDocument()) { + LOG(ERROR) << "Failed to create RenderView in EvaluateJavaScript"; + return; + } + } if (!callback) { // No callback requested. - host->ExecuteJavascriptInWebFrame(string16(), // frame_xpath - ConvertJavaStringToUTF16(env, script)); + rvh->ExecuteJavascriptInWebFrame(string16(), // frame_xpath + ConvertJavaStringToUTF16(env, script)); return; } @@ -1490,7 +1493,7 @@ void ContentViewCoreImpl::EvaluateJavaScript(JNIEnv* env, content::RenderViewHost::JavascriptResultCallback c_callback = base::Bind(&JavaScriptResultCallback, j_callback); - host->ExecuteJavascriptInWebFrameCallbackResult( + rvh->ExecuteJavascriptInWebFrameCallbackResult( string16(), // frame_xpath ConvertJavaStringToUTF16(env, script), c_callback); @@ -1498,7 +1501,7 @@ void ContentViewCoreImpl::EvaluateJavaScript(JNIEnv* env, bool ContentViewCoreImpl::GetUseDesktopUserAgent( JNIEnv* env, jobject obj) { - NavigationEntry* entry = web_contents_->GetController().GetActiveEntry(); + NavigationEntry* entry = web_contents_->GetController().GetVisibleEntry(); return entry && entry->GetIsOverridingUserAgent(); } @@ -1547,7 +1550,7 @@ void ContentViewCoreImpl::SetUseDesktopUserAgent( return; // Make sure the navigation entry actually exists. - NavigationEntry* entry = web_contents_->GetController().GetActiveEntry(); + NavigationEntry* entry = web_contents_->GetController().GetVisibleEntry(); if (!entry) return; @@ -1571,12 +1574,17 @@ void ContentViewCoreImpl::SetAccessibilityEnabled(JNIEnv* env, jobject obj, return; RenderWidgetHostImpl* host_impl = RenderWidgetHostImpl::From( host_view->GetRenderWidgetHost()); + BrowserAccessibilityState* accessibility_state = + BrowserAccessibilityState::GetInstance(); if (enabled) { - BrowserAccessibilityState::GetInstance()->EnableAccessibility(); - if (host_impl) + // This enables accessibility globally unless it was explicitly disallowed + // by a command-line flag. + accessibility_state->OnScreenReaderDetected(); + // If it was actually enabled globally, enable it for this RenderWidget now. + if (accessibility_state->IsAccessibleBrowser() && host_impl) host_impl->SetAccessibilityMode(AccessibilityModeComplete); } else { - BrowserAccessibilityState::GetInstance()->DisableAccessibility(); + accessibility_state->DisableAccessibility(); if (host_impl) host_impl->SetAccessibilityMode(AccessibilityModeOff); } diff --git a/chromium/content/browser/android/content_view_core_impl.h b/chromium/content/browser/android/content_view_core_impl.h index ab7da6d2439..f3cf755257a 100644 --- a/chromium/content/browser/android/content_view_core_impl.h +++ b/chromium/content/browser/android/content_view_core_impl.h @@ -155,7 +155,8 @@ class ContentViewCoreImpl : public ContentViewCore, void EvaluateJavaScript(JNIEnv* env, jobject obj, jstring script, - jobject callback); + jobject callback, + jboolean start_renderer); int GetNativeImeAdapter(JNIEnv* env, jobject obj); void SetFocus(JNIEnv* env, jobject obj, jboolean focused); void ScrollFocusedEditableNodeIntoView(JNIEnv* env, jobject obj); diff --git a/chromium/content/browser/android/in_process/synchronous_compositor_impl.cc b/chromium/content/browser/android/in_process/synchronous_compositor_impl.cc index 678f622875b..5ab105b9a70 100644 --- a/chromium/content/browser/android/in_process/synchronous_compositor_impl.cc +++ b/chromium/content/browser/android/in_process/synchronous_compositor_impl.cc @@ -70,7 +70,7 @@ class SynchronousCompositorFactoryImpl : public SynchronousCompositorFactory { if (!offscreen_context_for_main_thread_.get() || offscreen_context_for_main_thread_->DestroyedOnMainThread()) { offscreen_context_for_main_thread_ = - webkit::gpu::ContextProviderInProcess::CreateOffscreen(); + webkit::gpu::ContextProviderInProcess::Create(); if (offscreen_context_for_main_thread_.get() && !offscreen_context_for_main_thread_->BindToCurrentThread()) offscreen_context_for_main_thread_ = NULL; @@ -90,7 +90,7 @@ class SynchronousCompositorFactoryImpl : public SynchronousCompositorFactory { if (!offscreen_context_for_compositor_thread_.get() || offscreen_context_for_compositor_thread_->DestroyedOnMainThread()) { offscreen_context_for_compositor_thread_ = - webkit::gpu::ContextProviderInProcess::CreateOffscreen(); + webkit::gpu::ContextProviderInProcess::Create(); } return offscreen_context_for_compositor_thread_; } @@ -228,7 +228,8 @@ void SynchronousCompositorImpl::SetInputHandler( void SynchronousCompositorImpl::DidOverscroll( const cc::DidOverscrollParams& params) { if (compositor_client_) { - compositor_client_->DidOverscroll(params.latest_overscroll_delta, + compositor_client_->DidOverscroll(params.accumulated_overscroll, + params.latest_overscroll_delta, params.current_fling_velocity); } } diff --git a/chromium/content/browser/android/web_contents_observer_android.cc b/chromium/content/browser/android/web_contents_observer_android.cc index d9a150742d1..eac49b240ae 100644 --- a/chromium/content/browser/android/web_contents_observer_android.cc +++ b/chromium/content/browser/android/web_contents_observer_android.cc @@ -15,6 +15,7 @@ #include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/public/browser/navigation_details.h" +#include "content/public/browser/navigation_entry.h" #include "jni/WebContentsObserverAndroid_jni.h" using base::android::AttachCurrentThread; @@ -66,8 +67,8 @@ void WebContentsObserverAndroid::DidStartLoading( ScopedJavaLocalRef<jobject> obj(weak_java_observer_.get(env)); if (obj.is_null()) return; - ScopedJavaLocalRef<jstring> jstring_url(ConvertUTF8ToJavaString( - env, web_contents()->GetVisibleURL().spec())); + ScopedJavaLocalRef<jstring> jstring_url( + ConvertUTF8ToJavaString(env, web_contents()->GetURL().spec())); Java_WebContentsObserverAndroid_didStartLoading( env, obj.obj(), jstring_url.obj()); } @@ -78,8 +79,19 @@ void WebContentsObserverAndroid::DidStopLoading( ScopedJavaLocalRef<jobject> obj(weak_java_observer_.get(env)); if (obj.is_null()) return; - ScopedJavaLocalRef<jstring> jstring_url(ConvertUTF8ToJavaString( - env, web_contents()->GetLastCommittedURL().spec())); + + std::string url_string; + NavigationEntry* entry = + web_contents()->GetController().GetLastCommittedEntry(); + // Not that GetBaseURLForDataURL is only used by the Android WebView + if (entry && !entry->GetBaseURLForDataURL().is_empty()) { + url_string = entry->GetBaseURLForDataURL().possibly_invalid_spec(); + } else { + url_string = web_contents()->GetURL().spec(); + } + + ScopedJavaLocalRef<jstring> jstring_url( + ConvertUTF8ToJavaString(env, url_string)); Java_WebContentsObserverAndroid_didStopLoading( env, obj.obj(), jstring_url.obj()); } diff --git a/chromium/content/browser/aura/gpu_process_transport_factory.cc b/chromium/content/browser/aura/gpu_process_transport_factory.cc index eeb6f3bc578..47b1533ae77 100644 --- a/chromium/content/browser/aura/gpu_process_transport_factory.cc +++ b/chromium/content/browser/aura/gpu_process_transport_factory.cc @@ -199,6 +199,12 @@ GpuProcessTransportFactory::CreateOffscreenCommandBufferContext() { return CreateContextCommon(swap_client, 0); } +scoped_ptr<WebKit::WebGraphicsContext3D> +GpuProcessTransportFactory::CreateOffscreenContext() { + return CreateOffscreenCommandBufferContext() + .PassAs<WebKit::WebGraphicsContext3D>(); +} + scoped_ptr<cc::SoftwareOutputDevice> CreateSoftwareOutputDevice( ui::Compositor* compositor) { #if defined(OS_WIN) diff --git a/chromium/content/browser/aura/gpu_process_transport_factory.h b/chromium/content/browser/aura/gpu_process_transport_factory.h index 56d3e55498a..72b88d532bb 100644 --- a/chromium/content/browser/aura/gpu_process_transport_factory.h +++ b/chromium/content/browser/aura/gpu_process_transport_factory.h @@ -35,7 +35,9 @@ class GpuProcessTransportFactory scoped_ptr<WebGraphicsContext3DCommandBufferImpl> CreateOffscreenCommandBufferContext(); - // ui::ContextFactory implementation. + // ContextFactory implementation. + virtual scoped_ptr<WebKit::WebGraphicsContext3D> CreateOffscreenContext() + OVERRIDE; virtual scoped_ptr<cc::OutputSurface> CreateOutputSurface( ui::Compositor* compositor) OVERRIDE; virtual scoped_refptr<ui::Reflector> CreateReflector( @@ -44,10 +46,6 @@ class GpuProcessTransportFactory virtual void RemoveReflector( scoped_refptr<ui::Reflector> reflector) OVERRIDE; virtual void RemoveCompositor(ui::Compositor* compositor) OVERRIDE; - virtual scoped_refptr<cc::ContextProvider> - OffscreenContextProviderForMainThread() OVERRIDE; - virtual scoped_refptr<cc::ContextProvider> - OffscreenContextProviderForCompositorThread() OVERRIDE; virtual bool DoesCreateTestContexts() OVERRIDE; // ImageTransportFactory implementation. @@ -68,6 +66,12 @@ class GpuProcessTransportFactory virtual void RemoveObserver( ImageTransportFactoryObserver* observer) OVERRIDE; + // ui::ContextFactory implementation. + virtual scoped_refptr<cc::ContextProvider> + OffscreenContextProviderForMainThread() OVERRIDE; + virtual scoped_refptr<cc::ContextProvider> + OffscreenContextProviderForCompositorThread() OVERRIDE; + void OnLostContext(ui::Compositor* compositor); private: diff --git a/chromium/content/browser/aura/software_output_device_win.cc b/chromium/content/browser/aura/software_output_device_win.cc index 1a5af467b4e..0332e3e936d 100644 --- a/chromium/content/browser/aura/software_output_device_win.cc +++ b/chromium/content/browser/aura/software_output_device_win.cc @@ -11,7 +11,6 @@ #include "ui/gfx/canvas.h" #include "ui/gfx/canvas_skia_paint.h" #include "ui/gfx/gdi_util.h" -#include "ui/gfx/skia_util.h" namespace content { @@ -99,12 +98,4 @@ void SoftwareOutputDeviceWin::EndPaint(cc::SoftwareFrameData* frame_data) { } } -void SoftwareOutputDeviceWin::CopyToBitmap( - gfx::Rect rect, SkBitmap* output) { - DCHECK(contents_); - SkDevice* device = contents_->sk_canvas()->getDevice(); - const SkBitmap& bitmap = device->accessBitmap(false); - bitmap.extractSubset(output, gfx::RectToSkIRect(rect)); -} - } // namespace content diff --git a/chromium/content/browser/aura/software_output_device_win.h b/chromium/content/browser/aura/software_output_device_win.h index 9c0655b6f67..93568c2bd5b 100644 --- a/chromium/content/browser/aura/software_output_device_win.h +++ b/chromium/content/browser/aura/software_output_device_win.h @@ -28,7 +28,6 @@ class SoftwareOutputDeviceWin : public cc::SoftwareOutputDevice { virtual void Resize(gfx::Size viewport_size) OVERRIDE; virtual SkCanvas* BeginPaint(gfx::Rect damage_rect) OVERRIDE; virtual void EndPaint(cc::SoftwareFrameData* frame_data) OVERRIDE; - virtual void CopyToBitmap(gfx::Rect rect, SkBitmap* output) OVERRIDE; private: HWND hwnd_; diff --git a/chromium/content/browser/browser_plugin/browser_plugin_guest.cc b/chromium/content/browser/browser_plugin/browser_plugin_guest.cc index 31250b7d626..5f1ec69e8af 100644 --- a/chromium/content/browser/browser_plugin/browser_plugin_guest.cc +++ b/chromium/content/browser/browser_plugin/browser_plugin_guest.cc @@ -127,7 +127,7 @@ class BrowserPluginGuest::GeolocationRequest : public PermissionRequest { // in the fact whether the embedder/app has geolocation // permission. Therefore we use an invalid |bridge_id|. -1 /* bridge_id */, - web_contents->GetLastCommittedURL(), + web_contents->GetURL(), geolocation_callback); return; } @@ -348,7 +348,7 @@ BrowserPluginGuest::BrowserPluginGuest( embedder_visible_(true), next_permission_request_id_(browser_plugin::kInvalidPermissionRequestID), has_render_view_(has_render_view), - last_seen_auto_size_enabled_(false) { + is_in_destruction_(false) { DCHECK(web_contents); web_contents->SetDelegate(this); if (opener) @@ -422,6 +422,7 @@ int BrowserPluginGuest::RequestPermission( } void BrowserPluginGuest::Destroy() { + is_in_destruction_ = true; if (!attached() && opener()) opener()->pending_new_windows_.erase(this); DestroyUnattachedWindows(); @@ -765,10 +766,6 @@ WebContentsImpl* BrowserPluginGuest::GetWebContents() { base::SharedMemory* BrowserPluginGuest::GetDamageBufferFromEmbedder( const BrowserPluginHostMsg_ResizeGuest_Params& params) { - if (!attached()) { - LOG(WARNING) << "Attempting to map a damage buffer prior to attachment."; - return NULL; - } #if defined(OS_WIN) base::ProcessHandle handle = embedder_web_contents_->GetRenderProcessHost()->GetHandle(); @@ -1264,7 +1261,7 @@ void BrowserPluginGuest::OnLockMouse(bool user_gesture, base::Value::CreateBooleanValue(last_unlocked_by_target)); request_info.Set(browser_plugin::kURL, base::Value::CreateStringValue( - web_contents()->GetLastCommittedURL().spec())); + web_contents()->GetURL().spec())); RequestPermission(BROWSER_PLUGIN_PERMISSION_TYPE_POINTER_LOCK, new PointerLockRequest(this), @@ -1321,13 +1318,6 @@ void BrowserPluginGuest::OnResizeGuest( render_widget_host->NotifyScreenInfoChanged(); } } - // When autosize is turned off and as a result there is a layout change, we - // send a sizechanged event. - if (!auto_size_enabled_ && last_seen_auto_size_enabled_ && - !params.view_rect.size().IsEmpty() && delegate_) { - delegate_->SizeChanged(last_seen_view_size_, params.view_rect.size()); - last_seen_auto_size_enabled_ = false; - } // 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)) { @@ -1590,16 +1580,6 @@ void BrowserPluginGuest::OnUpdateRect( params.flags); relay_params.needs_ack = params.needs_ack; - bool size_changed = last_seen_view_size_ != params.view_size; - gfx::Size old_size = last_seen_view_size_; - last_seen_view_size_ = params.view_size; - - if ((auto_size_enabled_ || last_seen_auto_size_enabled_) && - size_changed && delegate_) { - delegate_->SizeChanged(old_size, last_seen_view_size_); - } - last_seen_auto_size_enabled_ = auto_size_enabled_; - // HW accelerated case, acknowledge resize only if (!params.needs_ack || !damage_buffer_) { relay_params.damage_buffer_sequence_id = 0; diff --git a/chromium/content/browser/browser_plugin/browser_plugin_guest.h b/chromium/content/browser/browser_plugin/browser_plugin_guest.h index ffe8d566145..6098cacca38 100644 --- a/chromium/content/browser/browser_plugin/browser_plugin_guest.h +++ b/chromium/content/browser/browser_plugin/browser_plugin_guest.h @@ -136,6 +136,7 @@ class CONTENT_EXPORT BrowserPluginGuest bool focused() const { return focused_; } bool visible() const { return guest_visible_; } void clear_damage_buffer() { damage_buffer_.reset(); } + bool is_in_destruction() { return is_in_destruction_; } BrowserPluginGuest* opener() const { return opener_.get(); } @@ -515,10 +516,7 @@ class CONTENT_EXPORT BrowserPluginGuest // this guest is attached. bool has_render_view_; - // Last seen size of guest contents (by OnUpdateRect). - gfx::Size last_seen_view_size_; - // Last seen autosize attribute state (by OnUpdateRect). - bool last_seen_auto_size_enabled_; + bool is_in_destruction_; // This is a queue of messages that are destined to be sent to the embedder // once the guest is attached to a particular embedder. diff --git a/chromium/content/browser/browser_plugin/browser_plugin_host_browsertest.cc b/chromium/content/browser/browser_plugin/browser_plugin_host_browsertest.cc index c50e8cfa8a3..4fc2ae80335 100644 --- a/chromium/content/browser/browser_plugin/browser_plugin_host_browsertest.cc +++ b/chromium/content/browser/browser_plugin/browser_plugin_host_browsertest.cc @@ -786,6 +786,63 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, FocusTracksEmbedder) { test_guest()->WaitForBlur(); } +// 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 = "/browser_plugin_embedder.html"; + const std::string embedder_code = + "document.getElementById('plugin').minwidth = 300;" + "document.getElementById('plugin').minheight = 200;" + "document.getElementById('plugin').maxwidth = 600;" + "document.getElementById('plugin').maxheight = 400;" + "document.getElementById('plugin').autosize = true;"; + StartBrowserPluginTest( + kEmbedderURL, kHTMLForGuestWithSize, true, embedder_code); + // Verify that the guest has been auto-sized. + test_guest()->WaitForViewSize(gfx::Size(300, 400)); +} + +// This test verifies that enabling autosize resizes the guest and triggers +// a 'sizechanged' event. +IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, AutoSizeAfterNavigation) { + const char* kEmbedderURL = "/browser_plugin_embedder.html"; + StartBrowserPluginTest( + kEmbedderURL, kHTMLForGuestWithSize, true, std::string()); + RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>( + test_embedder()->web_contents()->GetRenderViewHost()); + + { + const string16 expected_title = ASCIIToUTF16("AutoSize(300, 400)"); + content::TitleWatcher title_watcher(test_embedder()->web_contents(), + expected_title); + ExecuteSyncJSFunction( + rvh, + "document.getElementById('plugin').minwidth = 300;" + "document.getElementById('plugin').minheight = 200;" + "document.getElementById('plugin').maxwidth = 600;" + "document.getElementById('plugin').maxheight = 400;" + "document.getElementById('plugin').autosize = true;"); + string16 actual_title = title_watcher.WaitAndGetTitle(); + EXPECT_EQ(expected_title, actual_title); + } + { + // Change the minwidth and verify that it causes relayout. + const string16 expected_title = ASCIIToUTF16("AutoSize(350, 400)"); + content::TitleWatcher title_watcher(test_embedder()->web_contents(), + expected_title); + ExecuteSyncJSFunction( + rvh, "document.getElementById('plugin').minwidth = 350;"); + string16 actual_title = title_watcher.WaitAndGetTitle(); + EXPECT_EQ(expected_title, actual_title); + } + { + // Turn off autoSize and verify that the guest resizes to fit the container. + ExecuteSyncJSFunction( + rvh, "document.getElementById('plugin').autosize = null;"); + test_guest()->WaitForViewSize(gfx::Size(640, 480)); + } +} + // Test for regression http://crbug.com/162961. IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, GetRenderViewHostAtPositionTest) { const char kEmbedderURL[] = "/browser_plugin_embedder.html"; @@ -801,6 +858,79 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, GetRenderViewHostAtPositionTest) { test_embedder()->last_rvh_at_position_response()); } +// 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 = "/browser_plugin_embedder.html"; + const std::string embedder_code = + "document.getElementById('plugin').minwidth = 300;" + "document.getElementById('plugin').minheight = 200;" + "document.getElementById('plugin').maxwidth = 600;" + "document.getElementById('plugin').maxheight = 400;" + "document.getElementById('plugin').name = 'name';" + "document.getElementById('plugin').src = 'foo';" + "document.getElementById('plugin').autosize = '';"; + StartBrowserPluginTest( + kEmbedderURL, kHTMLForGuestWithSize, true, embedder_code); + RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>( + test_embedder()->web_contents()->GetRenderViewHost()); + RemoveAttributes(rvh, "maxheight, maxwidth, minheight, minwidth, autosize"); + + // Verify that the guest resizes to fit the container (and hasn't crashed). + test_guest()->WaitForViewSize(gfx::Size(640, 480)); + EXPECT_TRUE(IsAttributeNull(rvh, "maxheight")); + EXPECT_TRUE(IsAttributeNull(rvh, "maxwidth")); + EXPECT_TRUE(IsAttributeNull(rvh, "minheight")); + EXPECT_TRUE(IsAttributeNull(rvh, "minwidth")); + EXPECT_TRUE(IsAttributeNull(rvh, "autosize")); +} + +// This test verifies that autosize works when some of the parameters are unset. +IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, PartialAutosizeAttributes) { + const char* kEmbedderURL = "/browser_plugin_embedder.html"; + const std::string embedder_code = + "document.getElementById('plugin').minwidth = 300;" + "document.getElementById('plugin').minheight = 200;" + "document.getElementById('plugin').maxwidth = 700;" + "document.getElementById('plugin').maxheight = 600;" + "document.getElementById('plugin').autosize = '';"; + StartBrowserPluginTest( + kEmbedderURL, kHTMLForGuestWithSize, true, embedder_code); + RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>( + test_embedder()->web_contents()->GetRenderViewHost()); + { + // Remove an autosize attribute and verify that it causes relayout. + const string16 expected_title = ASCIIToUTF16("AutoSize(640, 400)"); + content::TitleWatcher title_watcher(test_embedder()->web_contents(), + expected_title); + RemoveAttributes(rvh, "minwidth"); + string16 actual_title = title_watcher.WaitAndGetTitle(); + EXPECT_EQ(expected_title, actual_title); + } + { + // Remove an autosize attribute and verify that it causes relayout. + // Also tests that when minwidth > maxwidth, minwidth = maxwidth. + const string16 expected_title = ASCIIToUTF16("AutoSize(700, 480)"); + content::TitleWatcher title_watcher(test_embedder()->web_contents(), + expected_title); + RemoveAttributes(rvh, "maxheight"); + ExecuteSyncJSFunction( + rvh, "document.getElementById('plugin').minwidth = 800;" + "document.getElementById('plugin').minheight = 800;"); + string16 actual_title = title_watcher.WaitAndGetTitle(); + EXPECT_EQ(expected_title, actual_title); + } + { + // Remove maxwidth and make sure the size returns to plugin size. + const string16 expected_title = ASCIIToUTF16("AutoSize(640, 480)"); + content::TitleWatcher title_watcher(test_embedder()->web_contents(), + expected_title); + RemoveAttributes(rvh, "maxwidth"); + string16 actual_title = title_watcher.WaitAndGetTitle(); + EXPECT_EQ(expected_title, actual_title); + } +} + // This test verifies that if IME is enabled in the embedder, it is also enabled // in the guest. IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, VerifyInputMethodActive) { diff --git a/chromium/content/browser/browser_thread_impl.h b/chromium/content/browser/browser_thread_impl.h index 167cc3b85a1..b16bb362351 100644 --- a/chromium/content/browser/browser_thread_impl.h +++ b/chromium/content/browser/browser_thread_impl.h @@ -60,7 +60,6 @@ class CONTENT_EXPORT BrowserThreadImpl : public BrowserThread, // For testing. friend class ContentTestSuiteBaseListener; - friend class TestBrowserThreadBundle; static void FlushThreadPoolHelper(); // The identifier of this thread. Only one thread can exist with a given diff --git a/chromium/content/browser/child_process_security_policy_impl.cc b/chromium/content/browser/child_process_security_policy_impl.cc index d7640d344df..aefbf71fa62 100644 --- a/chromium/content/browser/child_process_security_policy_impl.cc +++ b/chromium/content/browser/child_process_security_policy_impl.cc @@ -38,6 +38,7 @@ const int kReadFilePermissions = const int kWriteFilePermissions = base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_WRITE | + base::PLATFORM_FILE_APPEND | base::PLATFORM_FILE_EXCLUSIVE_WRITE | base::PLATFORM_FILE_ASYNC | base::PLATFORM_FILE_WRITE_ATTRIBUTES; diff --git a/chromium/content/browser/device_orientation/device_orientation_browsertest.cc b/chromium/content/browser/device_orientation/device_orientation_browsertest.cc index 095e85f310c..17d944614d7 100644 --- a/chromium/content/browser/device_orientation/device_orientation_browsertest.cc +++ b/chromium/content/browser/device_orientation/device_orientation_browsertest.cc @@ -71,7 +71,7 @@ IN_PROC_BROWSER_TEST_F(DeviceOrientationBrowserTest, BasicTest) { // Check that the page got the event it expected and that the provider // saw requests for adding and removing an observer. - EXPECT_EQ("pass", shell()->web_contents()->GetLastCommittedURL().ref()); + EXPECT_EQ("pass", shell()->web_contents()->GetURL().ref()); EXPECT_TRUE(provider->added_observer_); EXPECT_TRUE(provider->removed_observer_); } diff --git a/chromium/content/browser/devtools/devtools_protocol.cc b/chromium/content/browser/devtools/devtools_protocol.cc index 948ed6be8a4..83980846556 100644 --- a/chromium/content/browser/devtools/devtools_protocol.cc +++ b/chromium/content/browser/devtools/devtools_protocol.cc @@ -190,11 +190,6 @@ void DevToolsProtocol::Handler::SendNotification( SendRawMessage(notification->Serialize()); } -void DevToolsProtocol::Handler::SendAsyncResponse( - scoped_refptr<DevToolsProtocol::Response> response) { - SendRawMessage(response->Serialize()); -} - void DevToolsProtocol::Handler::SendRawMessage(const std::string& message) { if (!notifier_.is_null()) notifier_.Run(message); diff --git a/chromium/content/browser/devtools/devtools_protocol.h b/chromium/content/browser/devtools/devtools_protocol.h index 2f7ce0bfecb..0012947382c 100644 --- a/chromium/content/browser/devtools/devtools_protocol.h +++ b/chromium/content/browser/devtools/devtools_protocol.h @@ -141,8 +141,6 @@ class DevToolsProtocol { void SendNotification(const std::string& method, base::DictionaryValue* params); - void SendAsyncResponse(scoped_refptr<DevToolsProtocol::Response> response); - // Sends message to client, the caller is presumed to properly // format the message. void SendRawMessage(const std::string& message); diff --git a/chromium/content/browser/devtools/devtools_protocol_constants.cc b/chromium/content/browser/devtools/devtools_protocol_constants.cc index 7fbec4b665b..c689ea1b7cb 100644 --- a/chromium/content/browser/devtools/devtools_protocol_constants.cc +++ b/chromium/content/browser/devtools/devtools_protocol_constants.cc @@ -8,40 +8,32 @@ namespace content { namespace devtools { namespace Inspector { - namespace detached { const char kName[] = "Inspector.detached"; const char kParamReason[] = "reason"; } // detached - namespace targetCrashed { const char kName[] = "Inspector.targetCrashed"; } // targetCrashed - } // Inspector namespace DOM { - namespace setFileInputFiles { const char kName[] = "DOM.setFileInputFiles"; const char kParamFiles[] = "files"; } // setFileInputFiles - } // DOM namespace Page { - namespace handleJavaScriptDialog { const char kName[] = "Page.handleJavaScriptDialog"; const char kParamAccept[] = "accept"; const char kParamPromptText[] = "promptText"; } // handleJavaScriptDialog - namespace navigate { const char kName[] = "Page.navigate"; const char kParamUrl[] = "url"; } // navigate - namespace captureScreenshot { const char kName[] = "Page.captureScreenshot"; const char kParamFormat[] = "format"; @@ -49,31 +41,12 @@ namespace captureScreenshot { const char kParamScale[] = "scale"; const char kResponseData[] = "data"; } // captureScreenshot - -namespace startScreencast { - const char kName[] = "Page.startScreencast"; - const char kParamFormat[] = "format"; - const char kParamQuality[] = "quality"; - const char kParamScale[] = "scale"; -} // startScreencast - -namespace stopScreencast { - const char kName[] = "Page.stopScreencast"; -} // stopScreencast - -namespace screencastFrame { - const char kName[] = "Page.screencastFrame"; - const char kResponseData[] = "data"; -} // screencastFrame - } // Page namespace Worker { - namespace disconnectedFromWorker { const char kName[] = "Worker.disconnectedFromWorker"; } // disconnectedFromWorker - } // Worker namespace Tracing { @@ -97,7 +70,6 @@ namespace dataCollected { const char kName[] = "Tracing.dataCollected"; const char kValue[] = "value"; } - } // Tracing } // devtools diff --git a/chromium/content/browser/devtools/devtools_protocol_constants.h b/chromium/content/browser/devtools/devtools_protocol_constants.h index fdf182a3dbb..a05493318e1 100644 --- a/chromium/content/browser/devtools/devtools_protocol_constants.h +++ b/chromium/content/browser/devtools/devtools_protocol_constants.h @@ -15,16 +15,13 @@ namespace content { namespace devtools { namespace Inspector { - namespace detached { extern const char kName[]; extern const char kParamReason[]; } // detached - namespace targetCrashed { extern const char kName[]; } // targetCrashed - } // Inspector namespace DOM { @@ -35,18 +32,15 @@ namespace setFileInputFiles { } // DOM namespace Page { - namespace handleJavaScriptDialog { extern const char kName[]; extern const char kParamAccept[]; extern const char kParamPromptText[]; } // handleJavaScriptDialog - namespace navigate { extern const char kName[]; extern const char kParamUrl[]; } // navigate - namespace captureScreenshot { extern const char kName[]; extern const char kParamFormat[]; @@ -54,23 +48,6 @@ namespace captureScreenshot { extern const char kParamScale[]; extern const char kResponseData[]; } // captureScreenshot - -namespace startScreencast { - extern const char kName[]; - extern const char kParamFormat[]; - extern const char kParamQuality[]; - extern const char kParamScale[]; -} // startScreencast - -namespace stopScreencast { - extern const char kName[]; -} // stopScreencast - -namespace screencastFrame { - extern const char kName[]; - extern const char kResponseData[]; -} // screencastFrame - } // Page namespace Tracing { @@ -98,11 +75,9 @@ namespace dataCollected { namespace Worker { - namespace disconnectedFromWorker { extern const char kName[]; } // disconnectedFromWorker - } // Worker } // devtools diff --git a/chromium/content/browser/devtools/render_view_devtools_agent_host.cc b/chromium/content/browser/devtools/render_view_devtools_agent_host.cc index 99686a00079..7455c160d8e 100644 --- a/chromium/content/browser/devtools/render_view_devtools_agent_host.cc +++ b/chromium/content/browser/devtools/render_view_devtools_agent_host.cc @@ -17,7 +17,6 @@ #include "content/browser/site_instance_impl.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/common/devtools_messages.h" -#include "content/common/view_messages.h" #include "content/public/browser/content_browser_client.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_types.h" @@ -312,17 +311,11 @@ bool RenderViewDevToolsAgentHost::OnRvhMessageReceived( IPC_MESSAGE_HANDLER(DevToolsHostMsg_ClearBrowserCache, OnClearBrowserCache) IPC_MESSAGE_HANDLER(DevToolsHostMsg_ClearBrowserCookies, OnClearBrowserCookies) - IPC_MESSAGE_HANDLER_GENERIC(ViewHostMsg_SwapCompositorFrame, - handled = false; OnSwapCompositorFrame()) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() return handled; } -void RenderViewDevToolsAgentHost::OnSwapCompositorFrame() { - overrides_handler_->OnSwapCompositorFrame(); -} - void RenderViewDevToolsAgentHost::OnSaveAgentRuntimeState( const std::string& state) { if (!render_view_host_) diff --git a/chromium/content/browser/devtools/render_view_devtools_agent_host.h b/chromium/content/browser/devtools/render_view_devtools_agent_host.h index 89855441146..00f73a6b2a0 100644 --- a/chromium/content/browser/devtools/render_view_devtools_agent_host.h +++ b/chromium/content/browser/devtools/render_view_devtools_agent_host.h @@ -59,7 +59,6 @@ class CONTENT_EXPORT RenderViewDevToolsAgentHost void RenderViewHostDestroyed(RenderViewHost* rvh); void RenderViewCrashed(); bool OnRvhMessageReceived(const IPC::Message& message); - void OnSwapCompositorFrame(); void OnDispatchOnInspectorFrontend(const std::string& message); void OnSaveAgentRuntimeState(const std::string& state); diff --git a/chromium/content/browser/devtools/renderer_overrides_handler.cc b/chromium/content/browser/devtools/renderer_overrides_handler.cc index f5d6c1cd546..57266676e87 100644 --- a/chromium/content/browser/devtools/renderer_overrides_handler.cc +++ b/chromium/content/browser/devtools/renderer_overrides_handler.cc @@ -34,7 +34,7 @@ #include "ui/snapshot/snapshot.h" #include "url/gurl.h" -namespace content { +using base::TimeTicks; namespace { @@ -42,31 +42,10 @@ static const char kPng[] = "png"; static const char kJpeg[] = "jpeg"; static int kDefaultScreenshotQuality = 80; -void ParseCaptureParameters(DevToolsProtocol::Command* command, - std::string* format, - int* quality, - double* scale) { - *quality = kDefaultScreenshotQuality; - *scale = 1; - base::DictionaryValue* params = command->params(); - if (params) { - params->GetString(devtools::Page::captureScreenshot::kParamFormat, - format); - params->GetInteger(devtools::Page::captureScreenshot::kParamQuality, - quality); - params->GetDouble(devtools::Page::captureScreenshot::kParamScale, - scale); - } - if (format->empty()) - *format = kPng; - if (*quality < 0 || *quality > 100) - *quality = kDefaultScreenshotQuality; - if (*scale <= 0 || *scale > 1) - *scale = 1; -} - } // namespace +namespace content { + RendererOverridesHandler::RendererOverridesHandler(DevToolsAgentHost* agent) : agent_(agent), weak_factory_(this) { @@ -90,45 +69,10 @@ RendererOverridesHandler::RendererOverridesHandler(DevToolsAgentHost* agent) base::Bind( &RendererOverridesHandler::PageCaptureScreenshot, base::Unretained(this))); - RegisterCommandHandler( - devtools::Page::startScreencast::kName, - base::Bind( - &RendererOverridesHandler::PageStartScreencast, - base::Unretained(this))); - RegisterCommandHandler( - devtools::Page::stopScreencast::kName, - base::Bind( - &RendererOverridesHandler::PageStopScreencast, - base::Unretained(this))); } RendererOverridesHandler::~RendererOverridesHandler() {} -void RendererOverridesHandler::OnSwapCompositorFrame() { - if (!screencast_command_) - return; - - std::string format; - int quality = kDefaultScreenshotQuality; - double scale = 1; - ParseCaptureParameters(screencast_command_.get(), &format, &quality, &scale); - - RenderViewHost* host = agent_->GetRenderViewHost(); - RenderWidgetHostViewPort* view_port = - RenderWidgetHostViewPort::FromRWHV(host->GetView()); - - gfx::Rect view_bounds = host->GetView()->GetViewBounds(); - gfx::Size snapshot_size = gfx::ToFlooredSize( - gfx::ScaleSize(view_bounds.size(), scale)); - - view_port->CopyFromCompositingSurface( - view_bounds, snapshot_size, - base::Bind(&RendererOverridesHandler::ScreenshotCaptured, - weak_factory_.GetWeakPtr(), - scoped_refptr<DevToolsProtocol::Command>(), format, quality, - scale)); -} - scoped_refptr<DevToolsProtocol::Response> RendererOverridesHandler::GrantPermissionsForSetFileInputFiles( scoped_refptr<DevToolsProtocol::Command> command) { @@ -211,10 +155,25 @@ RendererOverridesHandler::PageNavigate( scoped_refptr<DevToolsProtocol::Response> RendererOverridesHandler::PageCaptureScreenshot( scoped_refptr<DevToolsProtocol::Command> command) { + // Parse input parameters. std::string format; int quality = kDefaultScreenshotQuality; double scale = 1; - ParseCaptureParameters(command.get(), &format, &quality, &scale); + base::DictionaryValue* params = command->params(); + if (params) { + params->GetString(devtools::Page::captureScreenshot::kParamFormat, + &format); + params->GetInteger(devtools::Page::captureScreenshot::kParamQuality, + &quality); + params->GetDouble(devtools::Page::captureScreenshot::kParamScale, + &scale); + } + if (format.empty()) + format = kPng; + if (quality < 0 || quality > 100) + quality = kDefaultScreenshotQuality; + if (scale <= 0 || scale > 1) + scale = 1; RenderViewHost* host = agent_->GetRenderViewHost(); gfx::Rect view_bounds = host->GetView()->GetViewBounds(); @@ -251,21 +210,6 @@ RendererOverridesHandler::PageCaptureScreenshot( return command->AsyncResponsePromise(); } -scoped_refptr<DevToolsProtocol::Response> -RendererOverridesHandler::PageStartScreencast( - scoped_refptr<DevToolsProtocol::Command> command) { - screencast_command_ = command; - OnSwapCompositorFrame(); - return command->SuccessResponse(NULL); -} - -scoped_refptr<DevToolsProtocol::Response> -RendererOverridesHandler::PageStopScreencast( - scoped_refptr<DevToolsProtocol::Command> command) { - screencast_command_ = NULL; - return command->SuccessResponse(NULL); -} - void RendererOverridesHandler::ScreenshotCaptured( scoped_refptr<DevToolsProtocol::Command> command, const std::string& format, @@ -274,10 +218,9 @@ void RendererOverridesHandler::ScreenshotCaptured( bool success, const SkBitmap& bitmap) { if (!success) { - if (command) { - SendAsyncResponse( - command->InternalErrorResponse("Unable to capture screenshot")); - } + SendRawMessage( + command->InternalErrorResponse("Unable to capture screenshot")-> + Serialize()); return; } @@ -304,35 +247,27 @@ void RendererOverridesHandler::ScreenshotCaptured( } if (!encoded) { - if (command) { - SendAsyncResponse( - command->InternalErrorResponse("Unable to encode screenshot")); - } + SendRawMessage( + command->InternalErrorResponse("Unable to encode screenshot")-> + Serialize()); return; } std::string base_64_data; if (!base::Base64Encode(base::StringPiece( - reinterpret_cast<char*>(&data[0]), - data.size()), + reinterpret_cast<char*>(&data[0]), + data.size()), &base_64_data)) { - if (command) { - SendAsyncResponse( - command->InternalErrorResponse("Unable to base64 encode")); - } + SendRawMessage( + command->InternalErrorResponse("Unable to base64 encode screenshot")-> + Serialize()); return; } base::DictionaryValue* response = new base::DictionaryValue(); - if (command) { - response->SetString( - devtools::Page::captureScreenshot::kResponseData, base_64_data); - SendAsyncResponse(command->SuccessResponse(response)); - } else { - response->SetString( - devtools::Page::screencastFrame::kResponseData, base_64_data); - SendNotification(devtools::Page::screencastFrame::kName, response); - } + response->SetString( + devtools::Page::captureScreenshot::kResponseData, base_64_data); + SendRawMessage(command->SuccessResponse(response)->Serialize()); } } // namespace content diff --git a/chromium/content/browser/devtools/renderer_overrides_handler.h b/chromium/content/browser/devtools/renderer_overrides_handler.h index 7e5814b9d28..1d4213d8be6 100644 --- a/chromium/content/browser/devtools/renderer_overrides_handler.h +++ b/chromium/content/browser/devtools/renderer_overrides_handler.h @@ -26,8 +26,6 @@ class RendererOverridesHandler : public DevToolsProtocol::Handler { explicit RendererOverridesHandler(DevToolsAgentHost* agent); virtual ~RendererOverridesHandler(); - void OnSwapCompositorFrame(); - private: scoped_refptr<DevToolsProtocol::Response> GrantPermissionsForSetFileInputFiles( @@ -38,10 +36,6 @@ class RendererOverridesHandler : public DevToolsProtocol::Handler { scoped_refptr<DevToolsProtocol::Command> command); scoped_refptr<DevToolsProtocol::Response> PageCaptureScreenshot( scoped_refptr<DevToolsProtocol::Command> command); - scoped_refptr<DevToolsProtocol::Response> PageStartScreencast( - scoped_refptr<DevToolsProtocol::Command> command); - scoped_refptr<DevToolsProtocol::Response> PageStopScreencast( - scoped_refptr<DevToolsProtocol::Command> command); void ScreenshotCaptured( scoped_refptr<DevToolsProtocol::Command> command, @@ -53,7 +47,6 @@ class RendererOverridesHandler : public DevToolsProtocol::Handler { DevToolsAgentHost* agent_; base::WeakPtrFactory<RendererOverridesHandler> weak_factory_; - scoped_refptr<DevToolsProtocol::Command> screencast_command_; DISALLOW_COPY_AND_ASSIGN(RendererOverridesHandler); }; diff --git a/chromium/content/browser/dom_storage/dom_storage_browsertest.cc b/chromium/content/browser/dom_storage/dom_storage_browsertest.cc index 79955a8bf17..54da50a7272 100644 --- a/chromium/content/browser/dom_storage/dom_storage_browsertest.cc +++ b/chromium/content/browser/dom_storage/dom_storage_browsertest.cc @@ -25,8 +25,7 @@ class DOMStorageBrowserTest : public ContentBrowserTest { // a #pass or #fail ref. Shell* the_browser = incognito ? CreateOffTheRecordBrowser() : shell(); NavigateToURLBlockUntilNavigationsComplete(the_browser, test_url, 2); - std::string result = - the_browser->web_contents()->GetLastCommittedURL().ref(); + std::string result = the_browser->web_contents()->GetURL().ref(); if (result != "pass") { std::string js_result; ASSERT_TRUE(ExecuteScriptAndExtractString( diff --git a/chromium/content/browser/dom_storage/dom_storage_host.cc b/chromium/content/browser/dom_storage/dom_storage_host.cc index 14d288d8653..296d52ec6d7 100644 --- a/chromium/content/browser/dom_storage/dom_storage_host.cc +++ b/chromium/content/browser/dom_storage/dom_storage_host.cc @@ -30,8 +30,12 @@ bool DOMStorageHost::OpenStorageArea(int connection_id, int namespace_id, return false; // Indicates the renderer gave us very bad data. NamespaceAndArea references; references.namespace_ = context_->GetStorageNamespace(namespace_id); - if (!references.namespace_.get()) - return false; + if (!references.namespace_.get()) { + // TODO(michaeln): Fix crbug/134003 and return false here. + // Until then return true to avoid crashing the renderer for + // sending a bad message. + return true; + } references.area_ = references.namespace_->OpenStorageArea(origin); DCHECK(references.area_.get()); connections_[connection_id] = references; @@ -50,8 +54,12 @@ bool DOMStorageHost::ExtractAreaValues( int connection_id, DOMStorageValuesMap* map) { map->clear(); DOMStorageArea* area = GetOpenArea(connection_id); - if (!area) - return false; + if (!area) { + // TODO(michaeln): Fix crbug/134003 and return false here. + // Until then return true to avoid crashing the renderer + // for sending a bad message. + return true; + } if (!area->IsLoadedInMemory()) { DOMStorageNamespace* ns = GetNamespace(connection_id); DCHECK(ns); @@ -93,8 +101,12 @@ bool DOMStorageHost::SetAreaItem( const base::string16& value, const GURL& page_url, base::NullableString16* old_value) { DOMStorageArea* area = GetOpenArea(connection_id); - if (!area) - return false; + if (!area) { + // TODO(michaeln): Fix crbug/134003 and return false here. + // Until then return true to allow the renderer to operate + // to a limited degree out of its cache. + return true; + } if (!area->SetItem(key, value, old_value)) return false; if (old_value->is_null() || old_value->string() != value) diff --git a/chromium/content/browser/dom_storage/dom_storage_namespace.h b/chromium/content/browser/dom_storage/dom_storage_namespace.h index 8e67b032bb4..5860685f807 100644 --- a/chromium/content/browser/dom_storage/dom_storage_namespace.h +++ b/chromium/content/browser/dom_storage/dom_storage_namespace.h @@ -13,8 +13,6 @@ #include "content/common/content_export.h" #include "url/gurl.h" -class GURL; - namespace content { class DOMStorageArea; diff --git a/chromium/content/browser/dom_storage/session_storage_database.cc b/chromium/content/browser/dom_storage/session_storage_database.cc index bac3df7a67b..5fb0c90da3b 100644 --- a/chromium/content/browser/dom_storage/session_storage_database.cc +++ b/chromium/content/browser/dom_storage/session_storage_database.cc @@ -326,7 +326,7 @@ leveldb::Status SessionStorageDatabase::TryToOpen(leveldb::DB** db) { // The directory exists but a valid leveldb database might not exist inside it // (e.g., a subset of the needed files might be missing). Handle this // situation gracefully by creating the database now. - options.max_open_files = 0; // Use minimum. + options.max_open_files = 64; // Use minimum. options.create_if_missing = true; #if defined(OS_WIN) return leveldb::DB::Open(options, WideToUTF8(file_path_.value()), db); diff --git a/chromium/content/browser/dom_storage/session_storage_database_unittest.cc b/chromium/content/browser/dom_storage/session_storage_database_unittest.cc index 2f86c3b9918..9722d72925c 100644 --- a/chromium/content/browser/dom_storage/session_storage_database_unittest.cc +++ b/chromium/content/browser/dom_storage/session_storage_database_unittest.cc @@ -219,6 +219,7 @@ void SessionStorageDatabaseTest::CheckDatabaseConsistency() const { for (DataMap::const_iterator it = data.begin(); it != data.end(); ++it) { std::string namespace_id; + std::string origin; if (IsNamespaceKey(it->first, &namespace_id)) { found_namespace_ids.insert(namespace_id); ++valid_keys; diff --git a/chromium/content/browser/download/download_browsertest.cc b/chromium/content/browser/download/download_browsertest.cc index 516ae18d861..79ad19c9839 100644 --- a/chromium/content/browser/download/download_browsertest.cc +++ b/chromium/content/browser/download/download_browsertest.cc @@ -22,14 +22,12 @@ #include "content/public/browser/power_save_blocker.h" #include "content/public/common/content_switches.h" #include "content/public/common/webplugininfo.h" -#include "content/public/test/browser_test_utils.h" #include "content/public/test/download_test_observer.h" #include "content/public/test/test_file_error_injector.h" #include "content/public/test/test_utils.h" #include "content/shell/shell.h" #include "content/shell/shell_browser_context.h" #include "content/shell/shell_download_manager_delegate.h" -#include "content/shell/shell_network_delegate.h" #include "content/test/content_browser_test.h" #include "content/test/content_browser_test_utils.h" #include "content/test/net/url_request_mock_http_job.h" @@ -1600,42 +1598,4 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, CancelResumingDownload) { EXPECT_TRUE(EnsureNoPendingDownloads()); } -// Check that the cookie policy is correctly updated when downloading a file -// that redirects cross origin. -IN_PROC_BROWSER_TEST_F(DownloadContentTest, CookiePolicy) { - ASSERT_TRUE(test_server()->Start()); - net::HostPortPair host_port = test_server()->host_port_pair(); - DCHECK_EQ(host_port.host(), std::string("127.0.0.1")); - - // Block third-party cookies. - ShellNetworkDelegate::SetAcceptAllCookies(false); - - // |url| redirects to a different origin |download| which tries to set a - // cookie. - std::string download(base::StringPrintf( - "http://localhost:%d/set-cookie?A=B", host_port.port())); - GURL url(test_server()->GetURL("server-redirect?" + download)); - - // Download the file. - SetupEnsureNoPendingDownloads(); - scoped_ptr<DownloadUrlParameters> dl_params( - DownloadUrlParameters::FromWebContents(shell()->web_contents(), url)); - scoped_ptr<DownloadTestObserver> observer(CreateWaiter(shell(), 1)); - DownloadManagerForShell(shell())->DownloadUrl(dl_params.Pass()); - observer->WaitForFinished(); - - // Get the important info from other threads and check it. - EXPECT_TRUE(EnsureNoPendingDownloads()); - - std::vector<DownloadItem*> downloads; - DownloadManagerForShell(shell())->GetAllDownloads(&downloads); - ASSERT_EQ(1u, downloads.size()); - ASSERT_EQ(DownloadItem::COMPLETE, downloads[0]->GetState()); - - // Check that the cookies were correctly set. - EXPECT_EQ("A=B", - content::GetCookies(shell()->web_contents()->GetBrowserContext(), - GURL(download))); -} - } // namespace content diff --git a/chromium/content/browser/download/download_file_unittest.cc b/chromium/content/browser/download/download_file_unittest.cc index 49e418c85bc..867b76f6fef 100644 --- a/chromium/content/browser/download/download_file_unittest.cc +++ b/chromium/content/browser/download/download_file_unittest.cc @@ -76,7 +76,6 @@ class DownloadFileTest : public testing::Test { DownloadFileTest() : observer_(new StrictMock<MockDownloadDestinationObserver>), observer_factory_(observer_.get()), - input_stream_(NULL), bytes_(-1), bytes_per_sec_(-1), hash_state_("xyzzy"), diff --git a/chromium/content/browser/download/download_manager_impl_unittest.cc b/chromium/content/browser/download/download_manager_impl_unittest.cc index 0865c04b2fa..eba28339b51 100644 --- a/chromium/content/browser/download/download_manager_impl_unittest.cc +++ b/chromium/content/browser/download/download_manager_impl_unittest.cc @@ -435,8 +435,7 @@ class DownloadManagerTest : public testing::Test { static const size_t kTestDataLen; DownloadManagerTest() - : callback_called_(false), - ui_thread_(BrowserThread::UI, &message_loop_), + : ui_thread_(BrowserThread::UI, &message_loop_), file_thread_(BrowserThread::FILE, &message_loop_), next_download_id_(0) { } diff --git a/chromium/content/browser/download/download_resource_handler.cc b/chromium/content/browser/download/download_resource_handler.cc index ed4edff67fe..3b4844e6e68 100644 --- a/chromium/content/browser/download/download_resource_handler.cc +++ b/chromium/content/browser/download/download_resource_handler.cc @@ -103,9 +103,6 @@ bool DownloadResourceHandler::OnRequestRedirected( const GURL& url, ResourceResponse* response, bool* defer) { - // We treat a download as a main frame load, and thus update the policy URL - // on redirects. - request_->set_first_party_for_cookies(url); return true; } diff --git a/chromium/content/browser/download/download_resource_handler.h b/chromium/content/browser/download/download_resource_handler.h index 60fbc944387..d38068d5482 100644 --- a/chromium/content/browser/download/download_resource_handler.h +++ b/chromium/content/browser/download/download_resource_handler.h @@ -49,6 +49,7 @@ class CONTENT_EXPORT DownloadResourceHandler uint64 position, uint64 size) OVERRIDE; + // Not needed, as this event handler ought to be the final resource. virtual bool OnRequestRedirected(int request_id, const GURL& url, ResourceResponse* response, diff --git a/chromium/content/browser/download/file_metadata_unittest_linux.cc b/chromium/content/browser/download/file_metadata_unittest_linux.cc index 4a3ebca5a2c..bc8666e076c 100644 --- a/chromium/content/browser/download/file_metadata_unittest_linux.cc +++ b/chromium/content/browser/download/file_metadata_unittest_linux.cc @@ -30,8 +30,7 @@ class FileMetadataLinuxTest : public testing::Test { public: FileMetadataLinuxTest() : source_url_("http://www.source.com"), - referrer_url_("http://www.referrer.com"), - is_xattr_supported_(false) {} + referrer_url_("http://www.referrer.com") {} const base::FilePath& test_file() const { return test_file_; diff --git a/chromium/content/browser/download/save_package.cc b/chromium/content/browser/download/save_package.cc index 8a9781d82b0..a386a2be0c3 100644 --- a/chromium/content/browser/download/save_package.cc +++ b/chromium/content/browser/download/save_package.cc @@ -971,11 +971,11 @@ void SavePackage::DoSavingProcess() { // sub-resource's link can be replaced with local file path, which // sub-resource's link need to be replaced with absolute URL which // point to its internet address because it got error when saving its data. - + SaveItem* save_item = NULL; // Start a new SaveItem job if we still have job in waiting queue. if (waiting_item_queue_.size()) { DCHECK(wait_state_ == NET_FILES); - SaveItem* save_item = waiting_item_queue_.front(); + save_item = waiting_item_queue_.front(); if (save_item->save_source() != SaveFileCreateInfo::SAVE_FILE_FROM_DOM) { SaveNextFile(false); } else if (!in_process_count()) { diff --git a/chromium/content/browser/download/save_package_unittest.cc b/chromium/content/browser/download/save_package_unittest.cc index c0aa3f8862b..9c8f29f46be 100644 --- a/chromium/content/browser/download/save_package_unittest.cc +++ b/chromium/content/browser/download/save_package_unittest.cc @@ -434,7 +434,7 @@ TEST_F(SavePackageTest, TestGetUrlToBeSavedViewSource) { base::FilePath(kTestDir).Append(file_name)); NavigateAndCommit(view_source_url); EXPECT_EQ(actual_url, GetUrlToBeSaved()); - EXPECT_EQ(view_source_url, contents()->GetLastCommittedURL()); + EXPECT_EQ(view_source_url, contents()->GetURL()); } } // namespace content diff --git a/chromium/content/browser/fileapi/file_system_browsertest.cc b/chromium/content/browser/fileapi/file_system_browsertest.cc index 6a79a409bd9..7c464a36e9f 100644 --- a/chromium/content/browser/fileapi/file_system_browsertest.cc +++ b/chromium/content/browser/fileapi/file_system_browsertest.cc @@ -36,8 +36,7 @@ class FileSystemBrowserTest : public ContentBrowserTest { LOG(INFO) << "Navigating to URL and blocking."; NavigateToURLBlockUntilNavigationsComplete(the_browser, test_url, 2); LOG(INFO) << "Navigation done."; - std::string result = - the_browser->web_contents()->GetLastCommittedURL().ref(); + std::string result = the_browser->web_contents()->GetURL().ref(); if (result != "pass") { std::string js_result; ASSERT_TRUE(ExecuteScriptAndExtractString( diff --git a/chromium/content/browser/fileapi/fileapi_message_filter.cc b/chromium/content/browser/fileapi/fileapi_message_filter.cc index d5e903b3e9a..5641564cff9 100644 --- a/chromium/content/browser/fileapi/fileapi_message_filter.cc +++ b/chromium/content/browser/fileapi/fileapi_message_filter.cc @@ -441,8 +441,7 @@ void FileAPIMessageFilter::OnOpenFile( int request_id, const GURL& path, int file_flags) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); base::PlatformFileError error; - const int open_permissions = base::PLATFORM_FILE_OPEN | - (file_flags & fileapi::kOpenFilePermissions); + const int open_permissions = file_flags & fileapi::kOpenPepperFilePermissions; FileSystemURL url(context_->CrackURL(path)); if (!HasPermissionsForFile(url, open_permissions, &error)) { Send(new FileSystemMsg_DidFail(request_id, error)); @@ -463,7 +462,7 @@ void FileAPIMessageFilter::OnOpenFile( } operations_[request_id] = operation_runner()->OpenFile( - url, file_flags, PeerHandle(), + url, open_permissions, PeerHandle(), base::Bind(&FileAPIMessageFilter::DidOpenFile, this, request_id, quota_policy)); } diff --git a/chromium/content/browser/geolocation/core_location_data_provider_mac.h b/chromium/content/browser/geolocation/core_location_data_provider_mac.h new file mode 100644 index 00000000000..29204aa0d8c --- /dev/null +++ b/chromium/content/browser/geolocation/core_location_data_provider_mac.h @@ -0,0 +1,54 @@ +// 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. + +// This file declares a CoreLocation data provider class that allows the +// CoreLocation framework to run on the UI thread, since the Geolocation API's +// providers all live on the IO thread + +#ifndef CONTENT_BROWSER_GEOLOCATION_CORE_LOCATION_DATA_PROVIDER_H_ +#define CONTENT_BROWSER_GEOLOCATION_CORE_LOCATION_DATA_PROVIDER_H_ + +#include "base/mac/scoped_nsobject.h" +#include "base/memory/ref_counted.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/common/geoposition.h" + +#import <Foundation/Foundation.h> + +@class CoreLocationWrapperMac; + +namespace content { +class CoreLocationProviderMac; + +// Data provider class that allows CoreLocation to run in Chrome's UI thread +// while existing on any of Chrome's threads (in this case the IO thread) +class CoreLocationDataProviderMac + : public base::RefCountedThreadSafe<CoreLocationDataProviderMac> { + public: + CoreLocationDataProviderMac(); + + bool StartUpdating(CoreLocationProviderMac* provider); + void StopUpdating(); + + void UpdatePosition(Geoposition* position); + + private: + friend class base::RefCountedThreadSafe<CoreLocationDataProviderMac>; + ~CoreLocationDataProviderMac(); + + // These must execute in BrowserThread::UI + void StartUpdatingTask(); + void StopUpdatingTask(); + // This must execute in the origin thread (IO thread) + void PositionUpdated(Geoposition position); + + // The wrapper class that supplies this class with position data + base::scoped_nsobject<CoreLocationWrapperMac> wrapper_; + // The LocationProvider class that should receive position data + CoreLocationProviderMac* provider_; +}; + +} // namespace content + +#endif // CONTENT_BROWSER_GEOLOCATION_CORE_LOCATION_DATA_PROVIDER_H_ diff --git a/chromium/content/browser/geolocation/core_location_data_provider_mac.mm b/chromium/content/browser/geolocation/core_location_data_provider_mac.mm new file mode 100644 index 00000000000..8b1cf82c28b --- /dev/null +++ b/chromium/content/browser/geolocation/core_location_data_provider_mac.mm @@ -0,0 +1,256 @@ +// 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. + +// This file contains the class definitions for the CoreLocation data provider +// class and the accompanying Objective C wrapper class. This data provider +// is used to allow the CoreLocation wrapper to run on the UI thread, since +// CLLocationManager's start and stop updating methods must be called from a +// thread with an active NSRunLoop. Currently only the UI thread appears to +// fill that requirement. + +#include "content/browser/geolocation/core_location_data_provider_mac.h" + +#include "base/bind.h" +#include "base/logging.h" +#include "base/time/time.h" +#include "content/browser/geolocation/core_location_provider_mac.h" +#include "content/browser/geolocation/geolocation_provider_impl.h" + +using content::CoreLocationDataProviderMac; +using content::Geoposition; + +// A few required declarations since the CoreLocation headers are not available +// with the Mac OS X 10.5 SDK. +// TODO(jorgevillatoro): Remove these declarations when we build against 10.6 + +// This idea was borrowed from wifi_data_provider_corewlan_mac.mm +typedef double CLLocationDegrees; +typedef double CLLocationAccuracy; +typedef double CLLocationSpeed; +typedef double CLLocationDirection; +typedef double CLLocationDistance; +typedef struct { + CLLocationDegrees latitude; + CLLocationDegrees longitude; +} CLLocationCoordinate2D; + +enum { + kCLErrorLocationUnknown = 0, + kCLErrorDenied +}; + +@interface CLLocationManager : NSObject ++ (BOOL)locationServicesEnabled; +@property(assign) id delegate; +- (void)startUpdatingLocation; +- (void)stopUpdatingLocation; +@end + +@interface CLLocation : NSObject<NSCopying, NSCoding> +@property(readonly) CLLocationCoordinate2D coordinate; +@property(readonly) CLLocationDistance altitude; +@property(readonly) CLLocationAccuracy horizontalAccuracy; +@property(readonly) CLLocationAccuracy verticalAccuracy; +@property(readonly) CLLocationDirection course; +@property(readonly) CLLocationSpeed speed; +@end + +@protocol CLLocationManagerDelegate +- (void)locationManager:(CLLocationManager*)manager + didUpdateToLocation:(CLLocation*)newLocation + fromLocation:(CLLocation*)oldLocation; +- (void)locationManager:(CLLocationManager*)manager + didFailWithError:(NSError*)error; +@end + +// This wrapper class receives CLLocation objects from CoreLocation, converts +// them to Geoposition objects, and passes them on to the data provider class +// Note: This class has some specific threading requirements, inherited from +// CLLocationManager. The location manaager's start and stop updating +// methods must be called from a thread that has an active run loop (which +// seems to only be the UI thread) +@interface CoreLocationWrapperMac : NSObject<CLLocationManagerDelegate> +{ + @private + NSBundle* bundle_; + Class locationManagerClass_; + id locationManager_; + CoreLocationDataProviderMac* dataProvider_; +} + +- (id)initWithDataProvider:(CoreLocationDataProviderMac*)dataProvider; +- (void)dealloc; + +// Can be called from any thread since it does not require an NSRunLoop. However +// it is not threadsafe to receive concurrent calls until after a first +// successful call (to avoid |bundle_| being double initialized) +- (BOOL)locationDataAvailable; + +// These should always be called from BrowserThread::UI +- (void)startLocation; +- (void)stopLocation; + +// These should only be called by CLLocationManager +- (void)locationManager:(CLLocationManager*)manager + didUpdateToLocation:(CLLocation*)newLocation + fromLocation:(CLLocation*)oldLocation; +- (void)locationManager:(CLLocationManager*)manager + didFailWithError:(NSError*)error; +- (BOOL)loadCoreLocationBundle; + +@end + +@implementation CoreLocationWrapperMac + +- (id)initWithDataProvider:(CoreLocationDataProviderMac*)dataProvider { + DCHECK(dataProvider); + dataProvider_ = dataProvider; + self = [super init]; + return self; +} + +- (void)dealloc { + [locationManager_ setDelegate:nil]; + [locationManager_ release]; + [locationManagerClass_ release]; + [bundle_ release]; + [super dealloc]; +} + +// Load the bundle and check to see if location services are enabled +// but don't do anything else +- (BOOL)locationDataAvailable { + return ([self loadCoreLocationBundle] && + [locationManagerClass_ locationServicesEnabled]); +} + +- (void)startLocation { + if ([self locationDataAvailable]) { + if (!locationManager_) { + locationManager_ = [[locationManagerClass_ alloc] init]; + [locationManager_ setDelegate:self]; + } + [locationManager_ startUpdatingLocation]; + } +} + +- (void)stopLocation { + [locationManager_ stopUpdatingLocation]; +} + +- (void)locationManager:(CLLocationManager*)manager + didUpdateToLocation:(CLLocation*)newLocation + fromLocation:(CLLocation*)oldLocation { + Geoposition position; + position.latitude = [newLocation coordinate].latitude; + position.longitude = [newLocation coordinate].longitude; + position.altitude = [newLocation altitude]; + position.accuracy = [newLocation horizontalAccuracy]; + position.altitude_accuracy = [newLocation verticalAccuracy]; + position.speed = [newLocation speed]; + position.heading = [newLocation course]; + position.timestamp = base::Time::Now(); + position.error_code = Geoposition::ERROR_CODE_NONE; + dataProvider_->UpdatePosition(&position); +} + +- (void)locationManager:(CLLocationManager*)manager + didFailWithError:(NSError*)error { + Geoposition position; + switch ([error code]) { + case kCLErrorLocationUnknown: + position.error_code = Geoposition::ERROR_CODE_POSITION_UNAVAILABLE; + break; + case kCLErrorDenied: + position.error_code = Geoposition::ERROR_CODE_PERMISSION_DENIED; + break; + default: + NOTREACHED() << "Unknown CoreLocation error: " << [error code]; + return; + } + dataProvider_->UpdatePosition(&position); +} + +- (BOOL)loadCoreLocationBundle { + if (!bundle_) { + bundle_ = [[NSBundle alloc] + initWithPath:@"/System/Library/Frameworks/CoreLocation.framework"]; + if (!bundle_) { + DLOG(WARNING) << "Couldn't load CoreLocation Framework"; + return NO; + } + + locationManagerClass_ = [bundle_ classNamed:@"CLLocationManager"]; + } + + return YES; +} + +@end + +namespace content { + +CoreLocationDataProviderMac::CoreLocationDataProviderMac() { + if (base::MessageLoop::current() != + GeolocationProviderImpl::GetInstance()->message_loop()) { + NOTREACHED() << "CoreLocation data provider must be created on " + "the Geolocation thread."; + } + provider_ = NULL; + wrapper_.reset([[CoreLocationWrapperMac alloc] initWithDataProvider:this]); +} + +CoreLocationDataProviderMac::~CoreLocationDataProviderMac() { +} + +// Returns true if the CoreLocation wrapper can load the framework and +// location services are enabled. The pointer argument will only be accessed +// in the origin thread. +bool CoreLocationDataProviderMac:: + StartUpdating(CoreLocationProviderMac* provider) { + DCHECK(provider); + DCHECK(!provider_) << "StartUpdating called twice"; + if (![wrapper_ locationDataAvailable]) return false; + provider_ = provider; + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::Bind(&CoreLocationDataProviderMac::StartUpdatingTask, this)); + return true; +} + +// Clears provider_ so that any leftover messages from CoreLocation get ignored +void CoreLocationDataProviderMac::StopUpdating() { + provider_ = NULL; + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::Bind(&CoreLocationDataProviderMac::StopUpdatingTask, this)); +} + +void CoreLocationDataProviderMac::UpdatePosition(Geoposition *position) { + GeolocationProviderImpl::GetInstance()->message_loop()->PostTask( + FROM_HERE, + base::Bind(&CoreLocationDataProviderMac::PositionUpdated, this, + *position)); +} + +// Runs in BrowserThread::UI +void CoreLocationDataProviderMac::StartUpdatingTask() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + [wrapper_ startLocation]; +} + +// Runs in BrowserThread::UI +void CoreLocationDataProviderMac::StopUpdatingTask() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + [wrapper_ stopLocation]; +} + +void CoreLocationDataProviderMac::PositionUpdated(Geoposition position) { + DCHECK(base::MessageLoop::current() == + GeolocationProviderImpl::GetInstance()->message_loop()); + if (provider_) + provider_->SetPosition(&position); +} + +} // namespace content diff --git a/chromium/content/browser/geolocation/core_location_provider_mac.h b/chromium/content/browser/geolocation/core_location_provider_mac.h new file mode 100644 index 00000000000..b4186d4ffb8 --- /dev/null +++ b/chromium/content/browser/geolocation/core_location_provider_mac.h @@ -0,0 +1,40 @@ +// 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. + +// This file declares a CoreLocation provider that runs on Mac OS X (10.6). +// Public for testing only - for normal usage this header should not be +// required, as location_provider.h declares the needed factory function. + +#ifndef CONTENT_BROWSER_GEOLOCATION_CORE_LOCATION_PROVIDER_MAC_H_ +#define CONTENT_BROWSER_GEOLOCATION_CORE_LOCATION_PROVIDER_MAC_H_ + +#include "content/browser/geolocation/location_provider_base.h" +#include "content/public/common/geoposition.h" + +namespace content { +class CoreLocationDataProviderMac; + +class CoreLocationProviderMac : public LocationProviderBase { + public: + explicit CoreLocationProviderMac(); + virtual ~CoreLocationProviderMac(); + + // LocationProvider + virtual bool StartProvider(bool high_accuracy) OVERRIDE; + virtual void StopProvider() OVERRIDE; + virtual void GetPosition(Geoposition* position) OVERRIDE; + virtual void OnPermissionGranted() OVERRIDE; + + // Receives new positions and calls UpdateListeners + void SetPosition(Geoposition* position); + + private: + bool is_updating_; + CoreLocationDataProviderMac* data_provider_; + Geoposition position_; +}; + +} // namespace content + +#endif // CONTENT_BROWSER_GEOLOCATION_CORE_LOCATION_PROVIDER_MAC_H_ diff --git a/chromium/content/browser/geolocation/core_location_provider_mac.mm b/chromium/content/browser/geolocation/core_location_provider_mac.mm new file mode 100644 index 00000000000..1c3aca1195c --- /dev/null +++ b/chromium/content/browser/geolocation/core_location_provider_mac.mm @@ -0,0 +1,68 @@ +// 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/geolocation/core_location_provider_mac.h" + +#include "base/command_line.h" +#include "base/logging.h" +#include "content/browser/geolocation/core_location_data_provider_mac.h" +#include "content/public/common/content_switches.h" + +namespace content { + +CoreLocationProviderMac::CoreLocationProviderMac() + : is_updating_(false) { + data_provider_ = new CoreLocationDataProviderMac(); + data_provider_->AddRef(); +} + +CoreLocationProviderMac::~CoreLocationProviderMac() { + data_provider_->StopUpdating(); + data_provider_->Release(); +} + +bool CoreLocationProviderMac::StartProvider(bool high_accuracy) { + // StartProvider maybe called multiple times. For example, to update the high + // accuracy hint. + // TODO(jknotten): Support high_accuracy hint in underlying data provider. + if (is_updating_) + return true; + + is_updating_ = data_provider_->StartUpdating(this); + return true; +} + +void CoreLocationProviderMac::StopProvider() { + data_provider_->StopUpdating(); + is_updating_ = false; +} + +void CoreLocationProviderMac::GetPosition(Geoposition* position) { + DCHECK(position); + *position = position_; + DCHECK(position->Validate() || + position->error_code != Geoposition::ERROR_CODE_NONE); +} + +void CoreLocationProviderMac::OnPermissionGranted() { +} + +void CoreLocationProviderMac::SetPosition(Geoposition* position) { + DCHECK(position); + position_ = *position; + DCHECK(position->Validate() || + position->error_code != Geoposition::ERROR_CODE_NONE); + + NotifyCallback(position_); +} + +LocationProvider* NewSystemLocationProvider() { + if (CommandLine::ForCurrentProcess()->HasSwitch( + switches::kExperimentalLocationFeatures)) { + return new CoreLocationProviderMac; + } + return NULL; +} + +} // namespace content diff --git a/chromium/content/browser/geolocation/geolocation_provider_impl.h b/chromium/content/browser/geolocation/geolocation_provider_impl.h index 68e83a87968..d4b5afb1074 100644 --- a/chromium/content/browser/geolocation/geolocation_provider_impl.h +++ b/chromium/content/browser/geolocation/geolocation_provider_impl.h @@ -25,8 +25,11 @@ class GeolocationProviderTest; // This is the main API to the geolocation subsystem. The application will hold // a single instance of this class and can register multiple clients to be // notified of location changes: -// * Callbacks are registered by AddLocationUpdateCallback() and will keep -// receiving updates until unregistered by RemoveLocationUpdateCallback(). +// * Observers are registered by AddLocationUpdateCallback() and will keep +// receiving updates +// until unregistered by RemoveLocationUpdateCallback(). +// * Callbacks are registered by RequestCallback() and will be called exactly +// once when the next update becomes available. // The application must instantiate the GeolocationProvider on the IO thread and // must communicate with it on the same thread. // The underlying location arbitrator will only be enabled whilst there is at diff --git a/chromium/content/browser/geolocation/location_arbitrator_impl.cc b/chromium/content/browser/geolocation/location_arbitrator_impl.cc index 4befee2f4f8..49c1c10b85e 100644 --- a/chromium/content/browser/geolocation/location_arbitrator_impl.cc +++ b/chromium/content/browser/geolocation/location_arbitrator_impl.cc @@ -160,7 +160,7 @@ LocationProvider* GeolocationArbitratorImpl::NewNetworkLocationProvider( } LocationProvider* GeolocationArbitratorImpl::NewSystemLocationProvider() { -#if defined(OS_WIN) || defined(OS_MACOSX) +#if defined(OS_WIN) return NULL; #else return content::NewSystemLocationProvider(); diff --git a/chromium/content/browser/gpu/gpu_data_manager_impl_private.cc b/chromium/content/browser/gpu/gpu_data_manager_impl_private.cc index 8491508667d..654048847ec 100644 --- a/chromium/content/browser/gpu/gpu_data_manager_impl_private.cc +++ b/chromium/content/browser/gpu/gpu_data_manager_impl_private.cc @@ -42,6 +42,7 @@ #include "base/win/windows_version.h" #endif // OS_WIN #if defined(OS_ANDROID) +#include "base/android/build_info.h" #include "ui/gfx/android/device_display_info.h" #endif // OS_ANDROID @@ -278,12 +279,15 @@ void ApplyAndroidWorkarounds(const gpu::GPUInfo& gpu_info, bool is_nexus10 = gpu_info.machine_model.find("Nexus 10") != std::string::npos; + int sdk_int = base::android::BuildInfo::GetInstance()->sdk_int(); + // 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_nvidia || is_qualcomm || - is_broadcom) + if (is_vivante || is_img || is_mali_t604 || (is_nvidia && (sdk_int < 18)) || + is_qualcomm || is_broadcom) { command_line->AppendSwitch(switches::kEnableVirtualGLContexts); + } gfx::DeviceDisplayInfo info; int default_tile_size = 256; @@ -736,11 +740,6 @@ void GpuDataManagerImplPrivate::AppendGpuCommandLine( IntSetToString(gpu_driver_bugs_)); } - if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE) && - !command_line->HasSwitch(switches::kDisableAcceleratedVideoDecode)) { - command_line->AppendSwitch(switches::kDisableAcceleratedVideoDecode); - } - #if defined(OS_WIN) // DisplayLink 7.1 and earlier can cause the GPU process to crash on startup. // http://crbug.com/177611 diff --git a/chromium/content/browser/indexed_db/indexed_db_browsertest.cc b/chromium/content/browser/indexed_db/indexed_db_browsertest.cc index ac541e761d3..ab010cbd92a 100644 --- a/chromium/content/browser/indexed_db/indexed_db_browsertest.cc +++ b/chromium/content/browser/indexed_db/indexed_db_browsertest.cc @@ -46,8 +46,7 @@ class IndexedDBBrowserTest : public ContentBrowserTest { LOG(INFO) << "Navigating to URL and blocking."; NavigateToURLBlockUntilNavigationsComplete(the_browser, test_url, 2); LOG(INFO) << "Navigation done."; - std::string result = - the_browser->web_contents()->GetLastCommittedURL().ref(); + std::string result = the_browser->web_contents()->GetURL().ref(); if (result != "pass") { std::string js_result; ASSERT_TRUE(ExecuteScriptAndExtractString( diff --git a/chromium/content/browser/indexed_db/indexed_db_internals_ui.cc b/chromium/content/browser/indexed_db/indexed_db_internals_ui.cc index 230b7887552..a5c90c4117f 100644 --- a/chromium/content/browser/indexed_db/indexed_db_internals_ui.cc +++ b/chromium/content/browser/indexed_db/indexed_db_internals_ui.cc @@ -257,6 +257,9 @@ void IndexedDBInternalsUI::ForceCloseOriginOnIndexedDBThread( void IndexedDBInternalsUI::OnForcedClose(const base::FilePath& partition_path, const GURL& origin_url, size_t connection_count) { + + scoped_refptr<IndexedDBContextImpl> context; + web_ui()->CallJavascriptFunction( "indexeddb.onForcedClose", base::StringValue(partition_path.value()), @@ -278,7 +281,7 @@ void IndexedDBInternalsUI::OnDownloadDataReady( DownloadUrlParameters::FromWebContents(web_ui()->GetWebContents(), url)); DownloadManager* dlm = BrowserContext::GetDownloadManager(browser_context); - const GURL referrer(web_ui()->GetWebContents()->GetLastCommittedURL()); + const GURL referrer(web_ui()->GetWebContents()->GetURL()); dl_params->set_referrer( content::Referrer(referrer, WebKit::WebReferrerPolicyDefault)); diff --git a/chromium/content/browser/indexed_db/indexed_db_leveldb_coding.cc b/chromium/content/browser/indexed_db/indexed_db_leveldb_coding.cc index 61d32db9047..0086b82390a 100644 --- a/chromium/content/browser/indexed_db/indexed_db_leveldb_coding.cc +++ b/chromium/content/browser/indexed_db/indexed_db_leveldb_coding.cc @@ -744,10 +744,7 @@ int CompareEncodedIDBKeys(const std::string& key_a, namespace { template <typename KeyType> -int Compare(const StringPiece& a, - const StringPiece& b, - bool only_compare_index_keys, - bool* ok) { +int Compare(const StringPiece& a, const StringPiece& b, bool, bool* ok) { KeyType key_a; KeyType key_b; @@ -769,7 +766,7 @@ int Compare(const StringPiece& a, template <> int Compare<ExistsEntryKey>(const StringPiece& a, const StringPiece& b, - bool only_compare_index_keys, + bool, bool* ok) { KeyPrefix prefix_a; KeyPrefix prefix_b; @@ -796,7 +793,7 @@ int Compare<ExistsEntryKey>(const StringPiece& a, template <> int Compare<ObjectStoreDataKey>(const StringPiece& a, const StringPiece& b, - bool only_compare_index_keys, + bool, bool* ok) { KeyPrefix prefix_a; KeyPrefix prefix_b; @@ -823,7 +820,7 @@ int Compare<ObjectStoreDataKey>(const StringPiece& a, template <> int Compare<IndexDataKey>(const StringPiece& a, const StringPiece& b, - bool only_compare_index_keys, + bool ignore_duplicates, bool* ok) { KeyPrefix prefix_a; KeyPrefix prefix_b; @@ -848,7 +845,7 @@ int Compare<IndexDataKey>(const StringPiece& a, int result = CompareEncodedIDBKeys(&slice_a, &slice_b, ok); if (!*ok || result) return result; - if (only_compare_index_keys) + if (ignore_duplicates) return 0; // sequence number [optional] @@ -880,7 +877,7 @@ int Compare<IndexDataKey>(const StringPiece& a, int Compare(const StringPiece& a, const StringPiece& b, - bool only_compare_index_keys, + bool index_keys, bool* ok) { StringPiece slice_a(a); StringPiece slice_b(b); @@ -921,12 +918,11 @@ int Compare(const StringPiece& a, if (type_byte_a < kMaxSimpleGlobalMetaDataTypeByte) return 0; + const bool ignore_duplicates = false; if (type_byte_a == kDatabaseFreeListTypeByte) - return Compare<DatabaseFreeListKey>( - a, b, only_compare_index_keys, ok); + return Compare<DatabaseFreeListKey>(a, b, ignore_duplicates, ok); if (type_byte_a == kDatabaseNameTypeByte) - return Compare<DatabaseNameKey>( - a, b, /*only_compare_index_keys*/ false, ok); + return Compare<DatabaseNameKey>(a, b, ignore_duplicates, ok); break; } @@ -951,24 +947,19 @@ int Compare(const StringPiece& a, if (type_byte_a < DatabaseMetaDataKey::MAX_SIMPLE_METADATA_TYPE) return 0; + const bool ignore_duplicates = false; if (type_byte_a == kObjectStoreMetaDataTypeByte) - return Compare<ObjectStoreMetaDataKey>( - a, b, only_compare_index_keys, ok); + return Compare<ObjectStoreMetaDataKey>(a, b, ignore_duplicates, ok); if (type_byte_a == kIndexMetaDataTypeByte) - return Compare<IndexMetaDataKey>( - a, b, /*only_compare_index_keys*/ false, ok); + return Compare<IndexMetaDataKey>(a, b, ignore_duplicates, ok); if (type_byte_a == kObjectStoreFreeListTypeByte) - return Compare<ObjectStoreFreeListKey>( - a, b, only_compare_index_keys, ok); + return Compare<ObjectStoreFreeListKey>(a, b, ignore_duplicates, ok); if (type_byte_a == kIndexFreeListTypeByte) - return Compare<IndexFreeListKey>( - a, b, /*only_compare_index_keys*/ false, ok); + return Compare<IndexFreeListKey>(a, b, ignore_duplicates, ok); if (type_byte_a == kObjectStoreNamesTypeByte) - return Compare<ObjectStoreNamesKey>( - a, b, only_compare_index_keys, ok); + return Compare<ObjectStoreNamesKey>(a, b, ignore_duplicates, ok); if (type_byte_a == kIndexNamesKeyTypeByte) - return Compare<IndexNamesKey>( - a, b, /*only_compare_index_keys*/ false, ok); + return Compare<IndexNamesKey>(a, b, ignore_duplicates, ok); break; } @@ -978,8 +969,8 @@ int Compare(const StringPiece& a, // TODO(jsbell): This case of non-existing user keys should not have to be // handled this way. - return Compare<ObjectStoreDataKey>( - a, b, /*only_compare_index_keys*/ false, ok); + const bool ignore_duplicates = false; + return Compare<ObjectStoreDataKey>(a, b, ignore_duplicates, ok); } case KeyPrefix::EXISTS_ENTRY: { @@ -988,8 +979,8 @@ int Compare(const StringPiece& a, // TODO(jsbell): This case of non-existing user keys should not have to be // handled this way. - return Compare<ExistsEntryKey>( - a, b, /*only_compare_index_keys*/ false, ok); + const bool ignore_duplicates = false; + return Compare<ExistsEntryKey>(a, b, ignore_duplicates, ok); } case KeyPrefix::INDEX_DATA: { @@ -998,7 +989,8 @@ int Compare(const StringPiece& a, // TODO(jsbell): This case of non-existing user keys should not have to be // handled this way. - return Compare<IndexDataKey>(a, b, only_compare_index_keys, ok); + bool ignore_duplicates = index_keys; + return Compare<IndexDataKey>(a, b, ignore_duplicates, ok); } case KeyPrefix::INVALID_TYPE: @@ -1012,11 +1004,9 @@ int Compare(const StringPiece& a, } // namespace -int Compare(const StringPiece& a, - const StringPiece& b, - bool only_compare_index_keys) { +int Compare(const StringPiece& a, const StringPiece& b, bool index_keys) { bool ok; - int result = Compare(a, b, only_compare_index_keys, &ok); + int result = Compare(a, b, index_keys, &ok); DCHECK(ok); if (!ok) return 0; @@ -1792,7 +1782,7 @@ std::string IndexDataKey::EncodeMaxKey(int64 database_id, } int IndexDataKey::Compare(const IndexDataKey& other, - bool only_compare_index_keys, + bool ignore_duplicates, bool* ok) { DCHECK_GE(database_id_, 0); DCHECK_GE(object_store_id_, 0); @@ -1801,7 +1791,7 @@ int IndexDataKey::Compare(const IndexDataKey& other, CompareEncodedIDBKeys(encoded_user_key_, other.encoded_user_key_, ok); if (!*ok || result) return result; - if (only_compare_index_keys) + if (ignore_duplicates) return 0; result = CompareEncodedIDBKeys( encoded_primary_key_, other.encoded_primary_key_, ok); diff --git a/chromium/content/browser/indexed_db/indexed_db_leveldb_coding.h b/chromium/content/browser/indexed_db/indexed_db_leveldb_coding.h index 974c27a4fa2..ecd8b9b2d99 100644 --- a/chromium/content/browser/indexed_db/indexed_db_leveldb_coding.h +++ b/chromium/content/browser/indexed_db/indexed_db_leveldb_coding.h @@ -402,9 +402,7 @@ class IndexDataKey { CONTENT_EXPORT static std::string EncodeMaxKey(int64 database_id, int64 object_store_id, int64 index_id); - int Compare(const IndexDataKey& other, - bool only_compare_index_keys, - bool* ok); + int Compare(const IndexDataKey& other, bool ignore_duplicates, bool* ok); int64 DatabaseId() const; int64 ObjectStoreId() const; int64 IndexId() const; diff --git a/chromium/content/browser/media/webrtc_browsertest.cc b/chromium/content/browser/media/webrtc_browsertest.cc index 7cf48b0ad77..58b3d3fdcfc 100644 --- a/chromium/content/browser/media/webrtc_browsertest.cc +++ b/chromium/content/browser/media/webrtc_browsertest.cc @@ -46,10 +46,6 @@ class WebrtcBrowserTest: public ContentBrowserTest { virtual ~WebrtcBrowserTest() {} virtual void SetUpOnMainThread() OVERRIDE { - ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); - } - - virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { // We need fake devices in this test since we want to run on naked VMs. We // assume these switches are set by default in content_browsertests. ASSERT_TRUE(CommandLine::ForCurrentProcess()->HasSwitch( @@ -57,9 +53,7 @@ class WebrtcBrowserTest: public ContentBrowserTest { ASSERT_TRUE(CommandLine::ForCurrentProcess()->HasSwitch( switches::kUseFakeUIForMediaStream)); - // The video playback will not work without a GPU, so force its use here. - // This may not be available on all VMs though. - command_line->AppendSwitch(switches::kUseGpuInTests); + ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); } protected: diff --git a/chromium/content/browser/media/webrtc_internals_browsertest.cc b/chromium/content/browser/media/webrtc_internals_browsertest.cc index 71bbe53ed9f..19c25741822 100644 --- a/chromium/content/browser/media/webrtc_internals_browsertest.cc +++ b/chromium/content/browser/media/webrtc_internals_browsertest.cc @@ -575,11 +575,16 @@ IN_PROC_BROWSER_TEST_F(WebRTCInternalsBrowserTest, ConvertedGraphs) { } } +#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY) // Timing out on ARM linux bot: http://crbug.com/238490 -// Disabling due to failure on Linux, Mac, Win: http://crbug.com/272413 +#define MAYBE_WithRealPeerConnectionCall DISABLED_WithRealPeerConnectionCall +#else +#define MAYBE_WithRealPeerConnectionCall WithRealPeerConnectionCall +#endif + // Sanity check of the page content under a real PeerConnection call. IN_PROC_BROWSER_TEST_F(WebRTCInternalsBrowserTest, - DISABLED_WithRealPeerConnectionCall) { + MAYBE_WithRealPeerConnectionCall) { // Start a peerconnection call in the first window. ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); GURL url(embedded_test_server()->GetURL("/media/peerconnection-call.html")); diff --git a/chromium/content/browser/mime_registry_message_filter.cc b/chromium/content/browser/mime_registry_message_filter.cc index f23cc004e4b..49a050084c9 100644 --- a/chromium/content/browser/mime_registry_message_filter.cc +++ b/chromium/content/browser/mime_registry_message_filter.cc @@ -30,6 +30,8 @@ bool MimeRegistryMessageFilter::OnMessageReceived(const IPC::Message& message, OnGetMimeTypeFromExtension) IPC_MESSAGE_HANDLER(MimeRegistryMsg_GetMimeTypeFromFile, OnGetMimeTypeFromFile) + IPC_MESSAGE_HANDLER(MimeRegistryMsg_GetPreferredExtensionForMimeType, + OnGetPreferredExtensionForMimeType) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() return handled; @@ -45,4 +47,9 @@ void MimeRegistryMessageFilter::OnGetMimeTypeFromFile( net::GetMimeTypeFromFile(file_path, mime_type); } +void MimeRegistryMessageFilter::OnGetPreferredExtensionForMimeType( + const std::string& mime_type, base::FilePath::StringType* extension) { + net::GetPreferredExtensionForMimeType(mime_type, extension); +} + } // namespace content diff --git a/chromium/content/browser/mime_registry_message_filter.h b/chromium/content/browser/mime_registry_message_filter.h index e86fe190b1d..4a719a5f2f1 100644 --- a/chromium/content/browser/mime_registry_message_filter.h +++ b/chromium/content/browser/mime_registry_message_filter.h @@ -27,6 +27,9 @@ class MimeRegistryMessageFilter : public BrowserMessageFilter { std::string* mime_type); void OnGetMimeTypeFromFile(const base::FilePath& file_path, std::string* mime_type); + void OnGetPreferredExtensionForMimeType( + const std::string& mime_type, + base::FilePath::StringType* extension); }; } // namespace content diff --git a/chromium/content/browser/quota_dispatcher_host.cc b/chromium/content/browser/quota_dispatcher_host.cc index 89ee710fad1..f83ee3f7be9 100644 --- a/chromium/content/browser/quota_dispatcher_host.cc +++ b/chromium/content/browser/quota_dispatcher_host.cc @@ -24,9 +24,10 @@ namespace content { // sends back the response to the renderer/worker. class QuotaDispatcherHost::RequestDispatcher { public: - RequestDispatcher(QuotaDispatcherHost* dispatcher_host, + RequestDispatcher(base::WeakPtr<QuotaDispatcherHost> dispatcher_host, int request_id) : dispatcher_host_(dispatcher_host), + render_process_id_(dispatcher_host->process_id_), request_id_(request_id) { dispatcher_host_->outstanding_requests_.AddWithID(this, request_id_); } @@ -35,21 +36,26 @@ class QuotaDispatcherHost::RequestDispatcher { protected: // Subclass must call this when it's done with the request. void Completed() { - dispatcher_host_->outstanding_requests_.Remove(request_id_); + if (dispatcher_host_) + dispatcher_host_->outstanding_requests_.Remove(request_id_); } - QuotaDispatcherHost* dispatcher_host() const { return dispatcher_host_; } + QuotaDispatcherHost* dispatcher_host() const { + return dispatcher_host_.get(); + } quota::QuotaManager* quota_manager() const { - return dispatcher_host_->quota_manager_; + return dispatcher_host_ ? dispatcher_host_->quota_manager_ : NULL; } QuotaPermissionContext* permission_context() const { - return dispatcher_host_->permission_context_.get(); + return dispatcher_host_ ? + dispatcher_host_->permission_context_.get() : NULL; } - int render_process_id() const { return dispatcher_host_->process_id_; } + int render_process_id() const { return render_process_id_; } int request_id() const { return request_id_; } private: - QuotaDispatcherHost* dispatcher_host_; + base::WeakPtr<QuotaDispatcherHost> dispatcher_host_; + int render_process_id_; int request_id_; }; @@ -57,7 +63,7 @@ class QuotaDispatcherHost::QueryUsageAndQuotaDispatcher : public RequestDispatcher { public: QueryUsageAndQuotaDispatcher( - QuotaDispatcherHost* dispatcher_host, + base::WeakPtr<QuotaDispatcherHost> dispatcher_host, int request_id) : RequestDispatcher(dispatcher_host, request_id), weak_factory_(this) {} @@ -73,7 +79,8 @@ class QuotaDispatcherHost::QueryUsageAndQuotaDispatcher private: void DidQueryStorageUsageAndQuota( QuotaStatusCode status, int64 usage, int64 quota) { - DCHECK(dispatcher_host()); + if (!dispatcher_host()) + return; if (status != quota::kQuotaStatusOk) { dispatcher_host()->Send(new QuotaMsg_DidFail(request_id(), status)); } else { @@ -91,7 +98,7 @@ class QuotaDispatcherHost::RequestQuotaDispatcher public: typedef RequestQuotaDispatcher self_type; - RequestQuotaDispatcher(QuotaDispatcherHost* dispatcher_host, + RequestQuotaDispatcher(base::WeakPtr<QuotaDispatcherHost> dispatcher_host, int request_id, const GURL& origin, StorageType type, @@ -108,6 +115,7 @@ class QuotaDispatcherHost::RequestQuotaDispatcher virtual ~RequestQuotaDispatcher() {} void Start() { + DCHECK(dispatcher_host()); DCHECK(type_ == quota::kStorageTypeTemporary || type_ == quota::kStorageTypePersistent || type_ == quota::kStorageTypeSyncable); @@ -129,6 +137,8 @@ class QuotaDispatcherHost::RequestQuotaDispatcher StorageType type, QuotaStatusCode status, int64 quota) { + if (!dispatcher_host()) + return; DCHECK_EQ(type_, type); DCHECK_EQ(host_, host); if (status != quota::kQuotaStatusOk) { @@ -162,6 +172,8 @@ class QuotaDispatcherHost::RequestQuotaDispatcher void DidGetPermissionResponse( QuotaPermissionContext::QuotaPermissionResponse response) { + if (!dispatcher_host()) + return; if (response != QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_ALLOW) { // User didn't allow the new quota. Just returning the current quota. DidFinish(quota::kQuotaStatusOk, current_quota_); @@ -178,6 +190,8 @@ class QuotaDispatcherHost::RequestQuotaDispatcher } void DidFinish(QuotaStatusCode status, int64 granted_quota) { + if (!dispatcher_host()) + return; DCHECK(dispatcher_host()); if (status != quota::kQuotaStatusOk) { dispatcher_host()->Send(new QuotaMsg_DidFail(request_id(), status)); @@ -203,7 +217,8 @@ QuotaDispatcherHost::QuotaDispatcherHost( QuotaPermissionContext* permission_context) : process_id_(process_id), quota_manager_(quota_manager), - permission_context_(permission_context) { + permission_context_(permission_context), + weak_factory_(this) { } bool QuotaDispatcherHost::OnMessageReceived( @@ -227,7 +242,7 @@ void QuotaDispatcherHost::OnQueryStorageUsageAndQuota( const GURL& origin, StorageType type) { QueryUsageAndQuotaDispatcher* dispatcher = new QueryUsageAndQuotaDispatcher( - this, request_id); + weak_factory_.GetWeakPtr(), request_id); dispatcher->QueryStorageUsageAndQuota(origin, type); } @@ -251,7 +266,8 @@ void QuotaDispatcherHost::OnRequestStorageQuota( } RequestQuotaDispatcher* dispatcher = new RequestQuotaDispatcher( - this, request_id, origin, type, requested_size, render_view_id); + weak_factory_.GetWeakPtr(), request_id, origin, type, + requested_size, render_view_id); dispatcher->Start(); } diff --git a/chromium/content/browser/quota_dispatcher_host.h b/chromium/content/browser/quota_dispatcher_host.h index 724b2ad975f..64469c1a49a 100644 --- a/chromium/content/browser/quota_dispatcher_host.h +++ b/chromium/content/browser/quota_dispatcher_host.h @@ -60,6 +60,8 @@ class QuotaDispatcherHost : public BrowserMessageFilter { IDMap<RequestDispatcher, IDMapOwnPointer> outstanding_requests_; + base::WeakPtrFactory<QuotaDispatcherHost> weak_factory_; + DISALLOW_IMPLICIT_CONSTRUCTORS(QuotaDispatcherHost); }; diff --git a/chromium/content/browser/renderer_host/clipboard_message_filter.cc b/chromium/content/browser/renderer_host/clipboard_message_filter.cc index 2ad35468244..0e2426bf224 100644 --- a/chromium/content/browser/renderer_host/clipboard_message_filter.cc +++ b/chromium/content/browser/renderer_host/clipboard_message_filter.cc @@ -115,23 +115,24 @@ void ClipboardMessageFilter::OnWriteObjectsSync( void ClipboardMessageFilter::OnWriteObjectsAsync( const ui::Clipboard::ObjectMap& objects) { + // This async message doesn't support shared-memory based bitmaps; they must + // be removed otherwise we might dereference a rubbish pointer. + scoped_ptr<ui::Clipboard::ObjectMap> sanitized_objects( + new ui::Clipboard::ObjectMap(objects)); + sanitized_objects->erase(ui::Clipboard::CBF_SMBITMAP); + #if defined(OS_WIN) // We cannot write directly from the IO thread, and cannot service the IPC // on the UI thread. We'll copy the relevant data and post a task to preform // the write on the UI thread. - ui::Clipboard::ObjectMap* long_living_objects = - new ui::Clipboard::ObjectMap(objects); - - // This async message doesn't support shared-memory based bitmaps; they must - // be removed otherwise we might dereference a rubbish pointer. - long_living_objects->erase(ui::Clipboard::CBF_SMBITMAP); - BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, - base::Bind(&WriteObjectsOnUIThread, base::Owned(long_living_objects))); + base::Bind( + &WriteObjectsOnUIThread, base::Owned(sanitized_objects.release()))); #else - GetClipboard()->WriteObjects(ui::Clipboard::BUFFER_STANDARD, objects); + GetClipboard()->WriteObjects( + ui::Clipboard::BUFFER_STANDARD, *sanitized_objects.get()); #endif } @@ -198,6 +199,7 @@ void ClipboardMessageFilter::OnReadImageReply( const SkBitmap& bitmap, IPC::Message* reply_msg) { base::SharedMemoryHandle image_handle = base::SharedMemory::NULLHandle(); uint32 image_size = 0; + std::string reply_data; if (!bitmap.isNull()) { std::vector<unsigned char> png_data; SkAutoLockPixels lock(bitmap); diff --git a/chromium/content/browser/renderer_host/compositor_impl_android.cc b/chromium/content/browser/renderer_host/compositor_impl_android.cc index 94ab1393c84..53c42e4277a 100644 --- a/chromium/content/browser/renderer_host/compositor_impl_android.cc +++ b/chromium/content/browser/renderer_host/compositor_impl_android.cc @@ -394,9 +394,8 @@ scoped_ptr<cc::OutputSurface> CompositorImpl::CreateOutputSurface( false, CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE, 64 * 1024, // command buffer size - std::min(full_screen_texture_size_in_bytes, - kDefaultStartTransferBufferSize), - kDefaultMinTransferBufferSize, + 64 * 1024, // start transfer buffer size + 64 * 1024, // min transfer buffer size std::min(3 * full_screen_texture_size_in_bytes, kDefaultMaxTransferBufferSize))) { LOG(ERROR) << "Failed to create 3D context for compositor."; diff --git a/chromium/content/browser/renderer_host/image_transport_factory_android.cc b/chromium/content/browser/renderer_host/image_transport_factory_android.cc index efe9235f170..39071c9bec3 100644 --- a/chromium/content/browser/renderer_host/image_transport_factory_android.cc +++ b/chromium/content/browser/renderer_host/image_transport_factory_android.cc @@ -125,9 +125,8 @@ CmdBufferImageTransportFactory::CmdBufferImageTransportFactory() { false, CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE, 64 * 1024, // command buffer size - std::min(full_screen_texture_size_in_bytes, - kDefaultStartTransferBufferSize), - kDefaultMinTransferBufferSize, + 64 * 1024, // starting buffer size + 64 * 1024, // min buffer size std::min(3 * full_screen_texture_size_in_bytes, kDefaultMaxTransferBufferSize)); diff --git a/chromium/content/browser/renderer_host/input/immediate_input_router.cc b/chromium/content/browser/renderer_host/input/immediate_input_router.cc index 368619cc1e6..96e8bb9ac44 100644 --- a/chromium/content/browser/renderer_host/input/immediate_input_router.cc +++ b/chromium/content/browser/renderer_host/input/immediate_input_router.cc @@ -85,9 +85,6 @@ ImmediateInputRouter::ImmediateInputRouter( has_touch_handler_(false), touch_event_queue_(new TouchEventQueue(this)), gesture_event_filter_(new GestureEventFilter(this)) { - enable_no_touch_to_renderer_while_scrolling_ = - CommandLine::ForCurrentProcess()->GetSwitchValueASCII( - switches::kNoTouchToRendererWhileScrolling) == "1"; DCHECK(process); DCHECK(client); } @@ -202,7 +199,6 @@ void ImmediateInputRouter::SendKeyboardEvent( void ImmediateInputRouter::SendGestureEvent( const GestureEventWithLatencyInfo& gesture_event) { - HandleGestureScroll(gesture_event); if (!client_->OnSendGestureEvent(gesture_event)) return; FilterAndSendWebInputEvent(gesture_event.event, gesture_event.latency, false); @@ -256,7 +252,6 @@ void ImmediateInputRouter::SendTouchEventImmediately( void ImmediateInputRouter::SendGestureEventImmediately( const GestureEventWithLatencyInfo& gesture_event) { - HandleGestureScroll(gesture_event); if (!client_->OnSendGestureEventImmediately(gesture_event)) return; FilterAndSendWebInputEvent(gesture_event.event, gesture_event.latency, false); @@ -561,19 +556,4 @@ void ImmediateInputRouter::ProcessTouchAck( touch_event_queue_->ProcessTouchAck(ack_result, latency_info); } -void ImmediateInputRouter::HandleGestureScroll( - const GestureEventWithLatencyInfo& gesture_event) { - if (!enable_no_touch_to_renderer_while_scrolling_) - return; - - // Once scrolling is started stop forwarding touch move events to renderer. - if (gesture_event.event.type == WebInputEvent::GestureScrollBegin) - touch_event_queue_->set_no_touch_move_to_renderer(true); - - if (gesture_event.event.type == WebInputEvent::GestureScrollEnd || - gesture_event.event.type == WebInputEvent::GestureFlingStart) { - touch_event_queue_->set_no_touch_move_to_renderer(false); - } -} - } // namespace content diff --git a/chromium/content/browser/renderer_host/input/immediate_input_router.h b/chromium/content/browser/renderer_host/input/immediate_input_router.h index 0bfa19f111e..270ca3dc67e 100644 --- a/chromium/content/browser/renderer_host/input/immediate_input_router.h +++ b/chromium/content/browser/renderer_host/input/immediate_input_router.h @@ -73,8 +73,6 @@ class CONTENT_EXPORT ImmediateInputRouter } private: - friend class ImmediateInputRouterTest; - // TouchEventQueueClient virtual void OnTouchEventAck(const TouchEventWithLatencyInfo& event, InputEventAckState ack_result) OVERRIDE; @@ -129,9 +127,6 @@ private: void ProcessTouchAck(InputEventAckState ack_result, const ui::LatencyInfo& latency_info); - void HandleGestureScroll( - const GestureEventWithLatencyInfo& gesture_event); - int routing_id() const { return routing_id_; } @@ -191,10 +186,6 @@ private: // not sent to the renderer. bool has_touch_handler_; - // Whether enabling the optimization that sending no touch move events to - // renderer while scrolling. - bool enable_no_touch_to_renderer_while_scrolling_; - scoped_ptr<TouchEventQueue> touch_event_queue_; scoped_ptr<GestureEventFilter> gesture_event_filter_; diff --git a/chromium/content/browser/renderer_host/input/immediate_input_router_unittest.cc b/chromium/content/browser/renderer_host/input/immediate_input_router_unittest.cc index 371e02e01b3..ed725ee1a10 100644 --- a/chromium/content/browser/renderer_host/input/immediate_input_router_unittest.cc +++ b/chromium/content/browser/renderer_host/input/immediate_input_router_unittest.cc @@ -548,14 +548,6 @@ class ImmediateInputRouterTest : public testing::Test { return touch_event_queue()->GetLatestEvent().event; } - void EnableNoTouchToRendererWhileScrolling() { - input_router_->enable_no_touch_to_renderer_while_scrolling_ = true; - } - - bool no_touch_move_to_renderer() { - return touch_event_queue()->no_touch_move_to_renderer_; - } - TouchEventQueue* touch_event_queue() const { return input_router_->touch_event_queue(); } @@ -2173,93 +2165,4 @@ TEST_F(ImmediateInputRouterTest, UnhandledWheelEvent) { EXPECT_EQ(client_->acked_wheel_event().deltaY, -5); } -// Tests that no touch move events are sent to renderer during scrolling. -TEST_F(ImmediateInputRouterTest, NoTouchMoveWhileScroll) { - EnableNoTouchToRendererWhileScrolling(); - set_debounce_interval_time_ms(0); - input_router_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true)); - process_->sink().ClearMessages(); - - // First touch press. - PressTouchPoint(0, 1); - SendTouchEvent(); - EXPECT_EQ(1U, process_->sink().message_count()); - process_->sink().ClearMessages(); - SendInputEventACK(WebInputEvent::TouchStart, - INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - - // Touch move will trigger scroll. - MoveTouchPoint(0, 20, 5); - SendTouchEvent(); - EXPECT_EQ(1U, process_->sink().message_count()); - process_->sink().ClearMessages(); - SendInputEventACK(WebInputEvent::TouchMove, - INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - - SimulateGestureEvent(WebInputEvent::GestureScrollBegin, - WebGestureEvent::Touchscreen); - EXPECT_EQ(1U, process_->sink().message_count()); - EXPECT_TRUE(no_touch_move_to_renderer()); - process_->sink().ClearMessages(); - SendInputEventACK(WebInputEvent::GestureScrollBegin, - INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - - // Touch move should not be sent to renderer. - MoveTouchPoint(0, 30, 5); - SendTouchEvent(); - EXPECT_EQ(0U, process_->sink().message_count()); - process_->sink().ClearMessages(); - - // Touch moves become ScrollUpdate. - SimulateGestureScrollUpdateEvent(20, 4, 0); - EXPECT_TRUE(no_touch_move_to_renderer()); - process_->sink().ClearMessages(); - SendInputEventACK(WebInputEvent::GestureScrollUpdate, - INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - - // Touch move should not be sent to renderer. - MoveTouchPoint(0, 65, 10); - SendTouchEvent(); - EXPECT_EQ(0U, process_->sink().message_count()); - process_->sink().ClearMessages(); - - // Touch end should still be sent to renderer. - ReleaseTouchPoint(0); - SendTouchEvent(); - EXPECT_EQ(1U, process_->sink().message_count()); - process_->sink().ClearMessages(); - SendInputEventACK(WebInputEvent::TouchEnd, - INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - - // On GestureScrollEnd, resume sending touch moves to renderer. - SimulateGestureEvent(WebKit::WebInputEvent::GestureScrollEnd, - WebGestureEvent::Touchscreen); - EXPECT_EQ(1U, process_->sink().message_count()); - EXPECT_FALSE(no_touch_move_to_renderer()); - process_->sink().ClearMessages(); - SendInputEventACK(WebInputEvent::GestureScrollEnd, - INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - - // Now touch events should come through to renderer. - PressTouchPoint(80, 10); - SendTouchEvent(); - EXPECT_EQ(1U, process_->sink().message_count()); - process_->sink().ClearMessages(); - SendInputEventACK(WebInputEvent::TouchStart, - INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - - MoveTouchPoint(0, 80, 20); - SendTouchEvent(); - EXPECT_EQ(1U, process_->sink().message_count()); - process_->sink().ClearMessages(); - SendInputEventACK(WebInputEvent::TouchMove, - INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - - ReleaseTouchPoint(0); - SendTouchEvent(); - EXPECT_EQ(1U, process_->sink().message_count()); - process_->sink().ClearMessages(); - SendInputEventACK(WebInputEvent::TouchEnd, - INPUT_EVENT_ACK_STATE_NOT_CONSUMED); -} } // namespace content diff --git a/chromium/content/browser/renderer_host/input/touch_event_queue.cc b/chromium/content/browser/renderer_host/input/touch_event_queue.cc index e22c05d0f80..c1675b9952d 100644 --- a/chromium/content/browser/renderer_host/input/touch_event_queue.cc +++ b/chromium/content/browser/renderer_host/input/touch_event_queue.cc @@ -91,8 +91,7 @@ class CoalescedWebTouchEvent { TouchEventQueue::TouchEventQueue(TouchEventQueueClient* client) : client_(client), - dispatching_touch_ack_(false), - no_touch_move_to_renderer_(false) { + dispatching_touch_ack_(false) { DCHECK(client); } @@ -213,10 +212,6 @@ bool TouchEventQueue::ShouldForwardToRenderer( if (event.type == WebKit::WebInputEvent::TouchStart) return true; - if (event.type == WebKit::WebInputEvent::TouchMove && - no_touch_move_to_renderer_) - return false; - for (unsigned int i = 0; i < event.touchesLength; ++i) { const WebKit::WebTouchPoint& point = event.touches[i]; // If a point has been stationary, then don't take it into account. diff --git a/chromium/content/browser/renderer_host/input/touch_event_queue.h b/chromium/content/browser/renderer_host/input/touch_event_queue.h index 358fae9c50d..23dda66c38b 100644 --- a/chromium/content/browser/renderer_host/input/touch_event_queue.h +++ b/chromium/content/browser/renderer_host/input/touch_event_queue.h @@ -61,10 +61,6 @@ class TouchEventQueue { return touch_queue_.empty(); } - void set_no_touch_move_to_renderer(bool value) { - no_touch_move_to_renderer_ = value; - } - private: friend class MockRenderWidgetHost; friend class ImmediateInputRouterTest; @@ -92,11 +88,6 @@ class TouchEventQueue { // Used to defer touch forwarding when ack dispatch triggers |QueueEvent()|. bool dispatching_touch_ack_; - // Don't send touch move events to renderer. This is enabled when the page - // is scrolling. This behaviour is currently enabled only on aura behind a - // flag. - bool no_touch_move_to_renderer_; - DISALLOW_COPY_AND_ASSIGN(TouchEventQueue); }; diff --git a/chromium/content/browser/renderer_host/input/web_input_event_builders_win.cc b/chromium/content/browser/renderer_host/input/web_input_event_builders_win.cc index a5a9b20f615..ba081fd429b 100644 --- a/chromium/content/browser/renderer_host/input/web_input_event_builders_win.cc +++ b/chromium/content/browser/renderer_host/input/web_input_event_builders_win.cc @@ -428,20 +428,22 @@ WebMouseWheelEventBuilder::Build(HWND hwnd, UINT message, // reading articles. static const float kScrollbarPixelsPerLine = 100.0f / 3.0f; wheel_delta /= WHEEL_DELTA; - float scroll_delta = wheel_delta * kScrollbarPixelsPerLine; + float scroll_delta = wheel_delta; if (horizontal_scroll) { unsigned long scroll_chars = kDefaultScrollCharsPerWheelDelta; SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0, &scroll_chars, 0); // TODO(pkasting): Should probably have a different multiplier // scrollbarPixelsPerChar here. - scroll_delta *= static_cast<float>(scroll_chars); + scroll_delta *= static_cast<float>(scroll_chars) * kScrollbarPixelsPerLine; } else { unsigned long scroll_lines = kDefaultScrollLinesPerWheelDelta; SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &scroll_lines, 0); if (scroll_lines == WHEEL_PAGESCROLL) result.scrollByPage = true; - if (!result.scrollByPage) - scroll_delta *= static_cast<float>(scroll_lines); + if (!result.scrollByPage) { + scroll_delta *= + static_cast<float>(scroll_lines) * kScrollbarPixelsPerLine; + } } // Set scroll amount based on above calculations. WebKit expects positive diff --git a/chromium/content/browser/renderer_host/media/desktop_capture_device.cc b/chromium/content/browser/renderer_host/media/desktop_capture_device.cc index 9549633e80d..5a03e465533 100644 --- a/chromium/content/browser/renderer_host/media/desktop_capture_device.cc +++ b/chromium/content/browser/renderer_host/media/desktop_capture_device.cc @@ -23,19 +23,7 @@ namespace content { namespace { - const int kBytesPerPixel = 4; - -webrtc::DesktopRect ComputeLetterboxRect( - const webrtc::DesktopSize& max_size, - const webrtc::DesktopSize& source_size) { - gfx::Rect result = media::ComputeLetterboxRegion( - gfx::Rect(0, 0, max_size.width(), max_size.height()), - gfx::Size(source_size.width(), source_size.height())); - return webrtc::DesktopRect::MakeLTRB( - result.x(), result.y(), result.right(), result.bottom()); -} - } // namespace class DesktopCaptureDevice::Core @@ -46,7 +34,8 @@ class DesktopCaptureDevice::Core scoped_ptr<webrtc::DesktopCapturer> capturer); // Implementation of VideoCaptureDevice methods. - void Allocate(const media::VideoCaptureCapability& capture_format, + void Allocate(int width, int height, + int frame_rate, EventHandler* event_handler); void Start(); void Stop(); @@ -62,16 +51,11 @@ class DesktopCaptureDevice::Core // Helper methods that run on the |task_runner_|. Posted from the // corresponding public methods. - void DoAllocate(const media::VideoCaptureCapability& capture_format); + void DoAllocate(int width, int height, int frame_rate); void DoStart(); void DoStop(); void DoDeAllocate(); - // Chooses new output properties based on the supplied source size and the - // properties requested to Allocate(), and dispatches OnFrameInfo[Changed] - // notifications. - void RefreshCaptureFormat(const webrtc::DesktopSize& frame_size); - // Helper to schedule capture tasks. void ScheduleCaptureTimer(); @@ -94,23 +78,24 @@ class DesktopCaptureDevice::Core base::Lock event_handler_lock_; EventHandler* event_handler_; - // Requested video capture format (width, height, frame rate, etc). - media::VideoCaptureCapability requested_format_; + // Requested size specified to Allocate(). + webrtc::DesktopSize requested_size_; - // Actual video capture format being generated. - media::VideoCaptureCapability capture_format_; + // Frame rate specified to Allocate(). + int frame_rate_; - // Size of frame most recently captured from the source. - webrtc::DesktopSize previous_frame_size_; + // Empty until the first frame has been captured, and the output dimensions + // chosen based on the capture frame's size, and any caller-supplied + // size constraints. + webrtc::DesktopSize output_size_; - // DesktopFrame into which captured frames are down-scaled and/or letterboxed, - // depending upon the caller's requested capture capabilities. If frames can - // be returned to the caller directly then this is NULL. - scoped_ptr<webrtc::DesktopFrame> output_frame_; + // Size of the most recently received frame. + webrtc::DesktopSize previous_frame_size_; - // Sub-rectangle of |output_frame_| into which the source will be scaled - // and/or letterboxed. - webrtc::DesktopRect output_rect_; + // DesktopFrame into which captured frames are scaled, if the source size does + // not match |output_size_|. If the source and output have the same dimensions + // then this is NULL. + scoped_ptr<webrtc::DesktopFrame> scaled_frame_; // True between DoStart() and DoStop(). Can't just check |event_handler_| // because |event_handler_| is used on the caller thread. @@ -140,12 +125,12 @@ DesktopCaptureDevice::Core::Core( DesktopCaptureDevice::Core::~Core() { } -void DesktopCaptureDevice::Core::Allocate( - const media::VideoCaptureCapability& capture_format, - EventHandler* event_handler) { - DCHECK_GT(capture_format.width, 0); - DCHECK_GT(capture_format.height, 0); - DCHECK_GT(capture_format.frame_rate, 0); +void DesktopCaptureDevice::Core::Allocate(int width, int height, + int frame_rate, + EventHandler* event_handler) { + DCHECK_GT(width, 0); + DCHECK_GT(height, 0); + DCHECK_GT(frame_rate, 0); { base::AutoLock auto_lock(event_handler_lock_); @@ -154,7 +139,7 @@ void DesktopCaptureDevice::Core::Allocate( task_runner_->PostTask( FROM_HERE, - base::Bind(&Core::DoAllocate, this, capture_format)); + base::Bind(&Core::DoAllocate, this, width, height, frame_rate)); } void DesktopCaptureDevice::Core::Start() { @@ -195,76 +180,95 @@ void DesktopCaptureDevice::Core::OnCaptureCompleted( scoped_ptr<webrtc::DesktopFrame> owned_frame(frame); - // Handle initial frame size and size changes. - RefreshCaptureFormat(frame->size()); + // If an |output_size_| hasn't yet been chosen then choose one, based upon + // the source frame size and the requested size supplied to Allocate(). + if (output_size_.is_empty()) { + // Treat the requested size as upper bounds on width & height. + // TODO(wez): Constraints should be passed from getUserMedia to Allocate. + output_size_.set( + std::min(frame->size().width(), requested_size_.width()), + std::min(frame->size().height(), requested_size_.height())); + + // Inform the EventHandler of the output dimensions, format and frame rate. + media::VideoCaptureCapability caps; + caps.width = output_size_.width(); + caps.height = output_size_.height(); + caps.frame_rate = frame_rate_; + caps.color = media::VideoCaptureCapability::kARGB; + caps.expected_capture_delay = + base::Time::kMillisecondsPerSecond / frame_rate_; + caps.interlaced = false; + + base::AutoLock auto_lock(event_handler_lock_); + if (event_handler_) + event_handler_->OnFrameInfo(caps); + } if (!started_) return; - webrtc::DesktopSize output_size(capture_format_.width, - capture_format_.height); - size_t output_bytes = output_size.width() * output_size.height() * + size_t output_bytes = output_size_.width() * output_size_.height() * webrtc::DesktopFrame::kBytesPerPixel; - const uint8_t* output_data = NULL; - if (frame->size().equals(output_size)) { + if (frame->size().equals(output_size_)) { // If the captured frame matches the output size, we can return the pixel // data directly, without scaling. - output_data = frame->data(); - } else { - // Otherwise we need to down-scale and/or letterbox to the target format. - - // Allocate a buffer of the correct size to scale the frame into. - // |output_frame_| is cleared whenever |output_rect_| changes, so we don't - // need to worry about clearing out stale pixel data in letterboxed areas. - if (!output_frame_) { - output_frame_.reset(new webrtc::BasicDesktopFrame(output_size)); - memset(output_frame_->data(), 0, output_bytes); + scaled_frame_.reset(); + + base::AutoLock auto_lock(event_handler_lock_); + if (event_handler_) { + event_handler_->OnIncomingCapturedFrame( + frame->data(), output_bytes, base::Time::Now(), 0, false, false); } - DCHECK(output_frame_->size().equals(output_size)); - - // TODO(wez): Optimize this to scale only changed portions of the output, - // using ARGBScaleClip(). - uint8_t* output_rect_data = output_frame_->data() + - output_frame_->stride() * output_rect_.top() + - webrtc::DesktopFrame::kBytesPerPixel * output_rect_.left(); - libyuv::ARGBScale(frame->data(), frame->stride(), - frame->size().width(), frame->size().height(), - output_rect_data, output_frame_->stride(), - output_rect_.width(), output_rect_.height(), - libyuv::kFilterBilinear); - output_data = output_frame_->data(); + return; + } + + // If the output size differs from the frame size (e.g. the source has changed + // from its original dimensions, or the caller specified size constraints) + // then we need to scale the image. + if (!scaled_frame_) + scaled_frame_.reset(new webrtc::BasicDesktopFrame(output_size_)); + DCHECK(scaled_frame_->size().equals(output_size_)); + + // If the source frame size changed then clear |scaled_frame_|'s pixels. + if (!previous_frame_size_.equals(frame->size())) { + previous_frame_size_ = frame->size(); + memset(scaled_frame_->data(), 0, output_bytes); } + // Determine the output size preserving aspect, and center in output buffer. + gfx::Rect scaled_rect = media::ComputeLetterboxRegion( + gfx::Rect(0, 0, output_size_.width(), output_size_.height()), + gfx::Size(frame->size().width(), frame->size().height())); + uint8* scaled_data = scaled_frame_->data() + + scaled_frame_->stride() * scaled_rect.y() + + webrtc::DesktopFrame::kBytesPerPixel * scaled_rect.x(); + + // TODO(wez): Optimize this to scale only changed portions of the output, + // using ARGBScaleClip(). + libyuv::ARGBScale(frame->data(), frame->stride(), + frame->size().width(), frame->size().height(), + scaled_data, scaled_frame_->stride(), + scaled_rect.width(), scaled_rect.height(), + libyuv::kFilterBilinear); + base::AutoLock auto_lock(event_handler_lock_); if (event_handler_) { - event_handler_->OnIncomingCapturedFrame(output_data, output_bytes, - base::Time::Now(), 0, false, false); + event_handler_->OnIncomingCapturedFrame( + scaled_frame_->data(), output_bytes, + base::Time::Now(), 0, false, false); } } -void DesktopCaptureDevice::Core::DoAllocate( - const media::VideoCaptureCapability& capture_format) { +void DesktopCaptureDevice::Core::DoAllocate(int width, + int height, + int frame_rate) { DCHECK(task_runner_->RunsTasksOnCurrentThread()); DCHECK(desktop_capturer_); - requested_format_ = capture_format; - - // Store requested frame rate and calculate expected delay. - capture_format_.frame_rate = requested_format_.frame_rate; - capture_format_.expected_capture_delay = - base::Time::kMillisecondsPerSecond / requested_format_.frame_rate; - - // Support dynamic changes in resolution only if requester also does. - if (requested_format_.frame_size_type == - media::VariableResolutionVideoCaptureDevice) { - capture_format_.frame_size_type = - media::VariableResolutionVideoCaptureDevice; - } - - // This capturer always outputs ARGB, non-interlaced. - capture_format_.color = media::VideoCaptureCapability::kARGB; - capture_format_.interlaced = false; + requested_size_.set(width, height); + output_size_.set(0, 0); + frame_rate_ = frame_rate; desktop_capturer_->Start(this); @@ -284,63 +288,14 @@ void DesktopCaptureDevice::Core::DoStart() { void DesktopCaptureDevice::Core::DoStop() { DCHECK(task_runner_->RunsTasksOnCurrentThread()); started_ = false; - output_frame_.reset(); - previous_frame_size_.set(0, 0); + scaled_frame_.reset(); } void DesktopCaptureDevice::Core::DoDeAllocate() { DCHECK(task_runner_->RunsTasksOnCurrentThread()); DoStop(); desktop_capturer_.reset(); -} - -void DesktopCaptureDevice::Core::RefreshCaptureFormat( - const webrtc::DesktopSize& frame_size) { - if (previous_frame_size_.equals(frame_size)) - return; - - // Clear the output frame, if any, since it will either need resizing, or - // clearing of stale data in letterbox areas, anyway. - output_frame_.reset(); - - if (previous_frame_size_.is_empty() || - requested_format_.frame_size_type == - media::VariableResolutionVideoCaptureDevice) { - // If this is the first frame, or the receiver supports variable resolution - // then determine the output size by treating the requested width & height - // as maxima. - if (frame_size.width() > requested_format_.width || - frame_size.height() > requested_format_.height) { - output_rect_ = ComputeLetterboxRect( - webrtc::DesktopSize(requested_format_.width, - requested_format_.height), - frame_size); - output_rect_.Translate(-output_rect_.left(), -output_rect_.top()); - } else { - output_rect_ = webrtc::DesktopRect::MakeSize(frame_size); - } - capture_format_.width = output_rect_.width(); - capture_format_.height = output_rect_.height(); - - { - base::AutoLock auto_lock(event_handler_lock_); - if (event_handler_) { - if (previous_frame_size_.is_empty()) { - event_handler_->OnFrameInfo(capture_format_); - } else { - event_handler_->OnFrameInfoChanged(capture_format_); - } - } - } - } else { - // Otherwise the output frame size cannot change, so just scale and - // letterbox. - output_rect_ = ComputeLetterboxRect( - webrtc::DesktopSize(capture_format_.width, capture_format_.height), - frame_size); - } - - previous_frame_size_ = frame_size; + output_size_.set(0, 0); } void DesktopCaptureDevice::Core::ScheduleCaptureTimer() { @@ -348,7 +303,7 @@ void DesktopCaptureDevice::Core::ScheduleCaptureTimer() { capture_task_posted_ = true; task_runner_->PostDelayedTask( FROM_HERE, base::Bind(&Core::OnCaptureTimer, this), - base::TimeDelta::FromSeconds(1) / capture_format_.frame_rate); + base::TimeDelta::FromSeconds(1) / frame_rate_); } void DesktopCaptureDevice::Core::OnCaptureTimer() { @@ -439,8 +394,11 @@ DesktopCaptureDevice::~DesktopCaptureDevice() { void DesktopCaptureDevice::Allocate( const media::VideoCaptureCapability& capture_format, - EventHandler* event_handler) { - core_->Allocate(capture_format, event_handler); + EventHandler* observer) { + core_->Allocate(capture_format.width, + capture_format.height, + capture_format.frame_rate, + observer); } void DesktopCaptureDevice::Start() { diff --git a/chromium/content/browser/renderer_host/media/desktop_capture_device_unittest.cc b/chromium/content/browser/renderer_host/media/desktop_capture_device_unittest.cc index cf050f5a210..0f14585ea90 100644 --- a/chromium/content/browser/renderer_host/media/desktop_capture_device_unittest.cc +++ b/chromium/content/browser/renderer_host/media/desktop_capture_device_unittest.cc @@ -17,9 +17,7 @@ #include "third_party/webrtc/modules/desktop_capture/screen_capturer.h" using ::testing::_; -using ::testing::AnyNumber; using ::testing::DoAll; -using ::testing::Expectation; using ::testing::InvokeWithoutArgs; using ::testing::SaveArg; @@ -27,10 +25,6 @@ namespace content { namespace { -MATCHER_P2(EqualsCaptureCapability, width, height, "") { - return arg.width == width && arg.height == height; -} - const int kTestFrameWidth1 = 100; const int kTestFrameHeight1 = 100; const int kTestFrameWidth2 = 200; @@ -44,8 +38,6 @@ class MockFrameObserver : public media::VideoCaptureDevice::EventHandler { MOCK_METHOD0(ReserveOutputBuffer, scoped_refptr<media::VideoFrame>()); MOCK_METHOD0(OnError, void()); MOCK_METHOD1(OnFrameInfo, void(const media::VideoCaptureCapability& info)); - MOCK_METHOD1(OnFrameInfoChanged, - void(const media::VideoCaptureCapability& info)); MOCK_METHOD6(OnIncomingCapturedFrame, void(const uint8* data, int length, base::Time timestamp, @@ -149,9 +141,8 @@ TEST_F(DesktopCaptureDeviceTest, MAYBE_Capture) { EXPECT_EQ(caps.width * caps.height * 4, frame_size); } -// Test that screen capturer behaves correctly if the source frame size changes -// but the caller cannot cope with variable resolution output. -TEST_F(DesktopCaptureDeviceTest, ScreenResolutionChangeConstantResolution) { +// Test that screen capturer can handle resolution change without crashing. +TEST_F(DesktopCaptureDeviceTest, ScreenResolutionChange) { FakeScreenCapturer* mock_capturer = new FakeScreenCapturer(); DesktopCaptureDevice capture_device( @@ -163,14 +154,11 @@ TEST_F(DesktopCaptureDeviceTest, ScreenResolutionChangeConstantResolution) { int frame_size; MockFrameObserver frame_observer; - Expectation frame_info_called = EXPECT_CALL(frame_observer, OnFrameInfo(_)) + EXPECT_CALL(frame_observer, OnFrameInfo(_)) .WillOnce(SaveArg<0>(&caps)); - EXPECT_CALL(frame_observer, OnFrameInfoChanged(_)) - .Times(0); EXPECT_CALL(frame_observer, OnError()) .Times(0); EXPECT_CALL(frame_observer, OnIncomingCapturedFrame(_, _, _, _, _, _)) - .After(frame_info_called) .WillRepeatedly(DoAll( SaveArg<1>(&frame_size), InvokeWithoutArgs(&done_event, &base::WaitableEvent::Signal))); @@ -183,16 +171,13 @@ TEST_F(DesktopCaptureDeviceTest, ScreenResolutionChangeConstantResolution) { 0, false, media::ConstantResolutionVideoCaptureDevice); - capture_device.Allocate(capture_format, &frame_observer); capture_device.Start(); - - // Capture at least two frames, to ensure that the source frame size has - // changed while capturing. + // Capture first frame. EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout())); done_event.Reset(); + // Capture second frame. EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout())); - capture_device.Stop(); capture_device.DeAllocate(); @@ -205,67 +190,4 @@ TEST_F(DesktopCaptureDeviceTest, ScreenResolutionChangeConstantResolution) { EXPECT_EQ(caps.width * caps.height * 4, frame_size); } -// Test that screen capturer behaves correctly if the source frame size changes -// and the caller can cope with variable resolution output. -TEST_F(DesktopCaptureDeviceTest, ScreenResolutionChangeVariableResolution) { - FakeScreenCapturer* mock_capturer = new FakeScreenCapturer(); - - DesktopCaptureDevice capture_device( - worker_pool_->GetSequencedTaskRunner(worker_pool_->GetSequenceToken()), - scoped_ptr<webrtc::DesktopCapturer>(mock_capturer)); - - media::VideoCaptureCapability caps; - base::WaitableEvent done_event(false, false); - - MockFrameObserver frame_observer; - Expectation frame_info_called = EXPECT_CALL(frame_observer, OnFrameInfo(_)) - .WillOnce(SaveArg<0>(&caps)); - Expectation first_info_changed = EXPECT_CALL(frame_observer, - OnFrameInfoChanged(EqualsCaptureCapability(kTestFrameWidth2, - kTestFrameHeight2))) - .After(frame_info_called); - Expectation second_info_changed = EXPECT_CALL(frame_observer, - OnFrameInfoChanged(EqualsCaptureCapability(kTestFrameWidth1, - kTestFrameHeight1))) - .After(first_info_changed); - EXPECT_CALL(frame_observer, OnFrameInfoChanged(_)) - .Times(AnyNumber()) - .After(second_info_changed); - EXPECT_CALL(frame_observer, OnError()) - .Times(0); - EXPECT_CALL(frame_observer, OnIncomingCapturedFrame(_, _, _, _, _, _)) - .After(frame_info_called) - .WillRepeatedly( - InvokeWithoutArgs(&done_event, &base::WaitableEvent::Signal)); - - media::VideoCaptureCapability capture_format( - kTestFrameWidth2, - kTestFrameHeight2, - kFrameRate, - media::VideoCaptureCapability::kI420, - 0, - false, - media::VariableResolutionVideoCaptureDevice); - - capture_device.Allocate(capture_format, &frame_observer); - capture_device.Start(); - - // Capture at least three frames, to ensure that the source frame size has - // changed at least twice while capturing. - EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout())); - done_event.Reset(); - EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout())); - done_event.Reset(); - EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout())); - - capture_device.Stop(); - capture_device.DeAllocate(); - - EXPECT_EQ(kTestFrameWidth1, caps.width); - EXPECT_EQ(kTestFrameHeight1, caps.height); - EXPECT_EQ(kFrameRate, caps.frame_rate); - EXPECT_EQ(media::VideoCaptureCapability::kARGB, caps.color); - EXPECT_FALSE(caps.interlaced); -} - } // namespace content diff --git a/chromium/content/browser/renderer_host/p2p/OWNERS b/chromium/content/browser/renderer_host/p2p/OWNERS index f12c2d60e83..17c3a1e6983 100644 --- a/chromium/content/browser/renderer_host/p2p/OWNERS +++ b/chromium/content/browser/renderer_host/p2p/OWNERS @@ -1,3 +1,2 @@ -hclam@chromium.org -mallinath@chromium.org sergeyu@chromium.org +hclam@chromium.org diff --git a/chromium/content/browser/renderer_host/p2p/socket_host_tcp.cc b/chromium/content/browser/renderer_host/p2p/socket_host_tcp.cc index 314026e2438..8e13bf8f5b5 100644 --- a/chromium/content/browser/renderer_host/p2p/socket_host_tcp.cc +++ b/chromium/content/browser/renderer_host/p2p/socket_host_tcp.cc @@ -136,9 +136,7 @@ void P2PSocketHostTcpBase::OnConnected(int result) { StartTls(); } else { if (IsPseudoTlsClientSocket(type_)) { - scoped_ptr<net::StreamSocket> transport_socket = socket_.Pass(); - socket_.reset( - new jingle_glue::FakeSSLClientSocket(transport_socket.Pass())); + socket_.reset(new jingle_glue::FakeSSLClientSocket(socket_.release())); } // If we are not doing TLS, we are ready to send data now. @@ -157,7 +155,7 @@ void P2PSocketHostTcpBase::StartTls() { scoped_ptr<net::ClientSocketHandle> socket_handle( new net::ClientSocketHandle()); - socket_handle->SetSocket(socket_.Pass()); + socket_handle->set_socket(socket_.release()); net::SSLClientSocketContext context; context.cert_verifier = url_context_->GetURLRequestContext()->cert_verifier(); @@ -173,8 +171,8 @@ void P2PSocketHostTcpBase::StartTls() { net::ClientSocketFactory::GetDefaultFactory(); DCHECK(socket_factory); - socket_ = socket_factory->CreateSSLClientSocket( - socket_handle.Pass(), dest_host_port_pair, ssl_config, context); + socket_.reset(socket_factory->CreateSSLClientSocket( + socket_handle.release(), dest_host_port_pair, ssl_config, context)); int status = socket_->Connect( base::Bind(&P2PSocketHostTcpBase::ProcessTlsConnectDone, base::Unretained(this))); diff --git a/chromium/content/browser/renderer_host/pepper/pepper_tcp_socket.cc b/chromium/content/browser/renderer_host/pepper/pepper_tcp_socket.cc index 05b2e09993a..f05be8783ed 100644 --- a/chromium/content/browser/renderer_host/pepper/pepper_tcp_socket.cc +++ b/chromium/content/browser/renderer_host/pepper/pepper_tcp_socket.cc @@ -141,16 +141,16 @@ void PepperTCPSocket::SSLHandshake( connection_state_ = SSL_HANDSHAKE_IN_PROGRESS; // TODO(raymes,rsleevi): Use trusted/untrusted certificates when connecting. - scoped_ptr<net::ClientSocketHandle> handle(new net::ClientSocketHandle()); - handle->SetSocket(socket_.Pass()); + net::ClientSocketHandle* handle = new net::ClientSocketHandle(); + handle->set_socket(socket_.release()); net::ClientSocketFactory* factory = net::ClientSocketFactory::GetDefaultFactory(); net::HostPortPair host_port_pair(server_name, server_port); net::SSLClientSocketContext ssl_context; ssl_context.cert_verifier = manager_->GetCertVerifier(); ssl_context.transport_security_state = manager_->GetTransportSecurityState(); - socket_ = factory->CreateSSLClientSocket( - handle.Pass(), host_port_pair, manager_->ssl_config(), ssl_context); + socket_.reset(factory->CreateSSLClientSocket( + handle, host_port_pair, manager_->ssl_config(), ssl_context)); if (!socket_) { LOG(WARNING) << "Failed to create an SSL client socket."; OnSSLHandshakeCompleted(net::ERR_UNEXPECTED); diff --git a/chromium/content/browser/renderer_host/render_message_filter.cc b/chromium/content/browser/renderer_host/render_message_filter.cc index fc84eabf2bd..29e1e1f199a 100644 --- a/chromium/content/browser/renderer_host/render_message_filter.cc +++ b/chromium/content/browser/renderer_host/render_message_filter.cc @@ -459,6 +459,7 @@ void RenderMessageFilter::OnCreateWindow( bool can_create_window = GetContentClient()->browser()->CanCreateWindow( params.opener_url, + params.opener_top_level_frame_url, params.opener_security_origin, params.window_container_type, params.target_url, diff --git a/chromium/content/browser/renderer_host/render_process_host_impl.cc b/chromium/content/browser/renderer_host/render_process_host_impl.cc index e31aff2afc6..2dd784a4e69 100644 --- a/chromium/content/browser/renderer_host/render_process_host_impl.cc +++ b/chromium/content/browser/renderer_host/render_process_host_impl.cc @@ -943,7 +943,6 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer( switches::kEnableWebRtcAecRecordings, switches::kEnableWebRtcTcpServerSocket, switches::kEnableWebRtcHWDecoding, - switches::kEnableWebRtcHWEncoding, #endif switches::kDisableWebKitMediaSource, switches::kEnableOverscrollNotifications, diff --git a/chromium/content/browser/renderer_host/render_view_host_manager_browsertest.cc b/chromium/content/browser/renderer_host/render_view_host_manager_browsertest.cc index f5ebb76fc0a..4053d6593f2 100644 --- a/chromium/content/browser/renderer_host/render_view_host_manager_browsertest.cc +++ b/chromium/content/browser/renderer_host/render_view_host_manager_browsertest.cc @@ -86,7 +86,7 @@ IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, // Wait for the navigation in the new window to finish, if it hasn't. WaitForLoadStop(new_shell->web_contents()); EXPECT_EQ("/files/navigate_opener.html", - new_shell->web_contents()->GetLastCommittedURL().path()); + new_shell->web_contents()->GetURL().path()); // Should have the same SiteInstance. scoped_refptr<SiteInstance> blank_site_instance( @@ -153,8 +153,7 @@ IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, // Wait for the window to open. Shell* new_shell = new_shell_observer.GetShell(); - EXPECT_EQ("/files/title2.html", - new_shell->web_contents()->GetVisibleURL().path()); + EXPECT_EQ("/files/title2.html", new_shell->web_contents()->GetURL().path()); // Wait for the cross-site transition in the new tab to finish. WaitForLoadStop(new_shell->web_contents()); @@ -208,8 +207,7 @@ IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, Shell* new_shell = new_shell_observer.GetShell(); // Opens in new window. - EXPECT_EQ("/files/title2.html", - new_shell->web_contents()->GetVisibleURL().path()); + EXPECT_EQ("/files/title2.html", new_shell->web_contents()->GetURL().path()); // Wait for the cross-site transition in the new tab to finish. WaitForLoadStop(new_shell->web_contents()); @@ -264,7 +262,7 @@ IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, // Wait for the cross-site transition in the new tab to finish. WaitForLoadStop(new_shell->web_contents()); EXPECT_EQ("/files/title2.html", - new_shell->web_contents()->GetLastCommittedURL().path()); + new_shell->web_contents()->GetURL().path()); // Should have the same SiteInstance. scoped_refptr<SiteInstance> blank_site_instance( @@ -310,8 +308,7 @@ IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, // Opens in same window. EXPECT_EQ(1u, Shell::windows().size()); - EXPECT_EQ("/files/title2.html", - shell()->web_contents()->GetLastCommittedURL().path()); + EXPECT_EQ("/files/title2.html", shell()->web_contents()->GetURL().path()); // Should have the same SiteInstance. scoped_refptr<SiteInstance> noref_site_instance( @@ -379,7 +376,7 @@ IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, // Wait for the navigation in the new tab to finish, if it hasn't. WaitForLoadStop(new_shell->web_contents()); EXPECT_EQ("/files/navigate_opener.html", - new_shell->web_contents()->GetLastCommittedURL().path()); + new_shell->web_contents()->GetURL().path()); // Should have the same SiteInstance. scoped_refptr<SiteInstance> blank_site_instance( @@ -459,7 +456,7 @@ IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, DisownOpener) { // Wait for the navigation in the new tab to finish, if it hasn't. WaitForLoadStop(new_shell->web_contents()); EXPECT_EQ("/files/title2.html", - new_shell->web_contents()->GetLastCommittedURL().path()); + new_shell->web_contents()->GetURL().path()); // Should have the same SiteInstance. scoped_refptr<SiteInstance> blank_site_instance( @@ -565,8 +562,7 @@ IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, // send it to post_message.html on a different site. WebContents* foo_contents = new_shell->web_contents(); WaitForLoadStop(foo_contents); - EXPECT_EQ("/files/navigate_opener.html", - foo_contents->GetLastCommittedURL().path()); + EXPECT_EQ("/files/navigate_opener.html", foo_contents->GetURL().path()); NavigateToURL(new_shell, https_server.GetURL("files/post_message.html")); scoped_refptr<SiteInstance> foo_site_instance( foo_contents->GetSiteInstance()); @@ -585,7 +581,7 @@ IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, Shell* new_shell2 = new_shell_observer2.GetShell(); WebContents* new_contents = new_shell2->web_contents(); WaitForLoadStop(new_contents); - EXPECT_EQ("/files/title2.html", new_contents->GetLastCommittedURL().path()); + EXPECT_EQ("/files/title2.html", new_contents->GetURL().path()); NavigateToURL(new_shell2, test_server()->GetURL("files/post_message.html")); EXPECT_EQ(orig_site_instance, new_contents->GetSiteInstance()); RenderViewHostManager* new_manager = @@ -702,7 +698,7 @@ IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, // Wait for the navigation in the new window to finish, if it hasn't. WaitForLoadStop(new_shell->web_contents()); EXPECT_EQ("/files/navigate_opener.html", - new_shell->web_contents()->GetLastCommittedURL().path()); + new_shell->web_contents()->GetURL().path()); // Should have the same SiteInstance. scoped_refptr<SiteInstance> blank_site_instance( @@ -769,7 +765,7 @@ IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, // Wait for the navigation in the new window to finish, if it hasn't. WaitForLoadStop(new_shell->web_contents()); EXPECT_EQ("/files/navigate_opener.html", - new_shell->web_contents()->GetLastCommittedURL().path()); + new_shell->web_contents()->GetURL().path()); // Should have the same SiteInstance. scoped_refptr<SiteInstance> opened_site_instance( @@ -833,8 +829,7 @@ IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, ClickLinkAfter204Error) { scoped_refptr<SiteInstance> post_nav_site_instance( shell()->web_contents()->GetSiteInstance()); EXPECT_EQ(orig_site_instance, post_nav_site_instance); - EXPECT_EQ("/nocontent", - shell()->web_contents()->GetVisibleURL().path()); + EXPECT_EQ("/nocontent", shell()->web_contents()->GetURL().path()); EXPECT_EQ("/files/click-noreferrer-links.html", shell()->web_contents()->GetController(). GetLastCommittedEntry()->GetVirtualURL().path()); @@ -852,8 +847,7 @@ IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, ClickLinkAfter204Error) { // Opens in same tab. EXPECT_EQ(1u, Shell::windows().size()); - EXPECT_EQ("/files/title2.html", - shell()->web_contents()->GetLastCommittedURL().path()); + EXPECT_EQ("/files/title2.html", shell()->web_contents()->GetURL().path()); // Should have the same SiteInstance. scoped_refptr<SiteInstance> noref_site_instance( @@ -1079,7 +1073,7 @@ IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, // Wait for the navigation in the new tab to finish, if it hasn't. WaitForLoadStop(new_shell->web_contents()); EXPECT_EQ("/files/navigate_opener.html", - new_shell->web_contents()->GetLastCommittedURL().path()); + new_shell->web_contents()->GetURL().path()); RenderViewHost* rvh = new_shell->web_contents()->GetRenderViewHost(); @@ -1110,7 +1104,7 @@ IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, } EXPECT_EQ("/files/navigate_opener.html", - new_shell->web_contents()->GetLastCommittedURL().path()); + new_shell->web_contents()->GetURL().path()); EXPECT_EQ(rvh, new_shell->web_contents()->GetRenderViewHost()); @@ -1193,7 +1187,7 @@ IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, LeakingRenderViewHosts) { // view-source URL, we create a new SiteInstance. RenderViewHost* blank_rvh = shell()->web_contents()->GetRenderViewHost(); SiteInstance* blank_site_instance = blank_rvh->GetSiteInstance(); - EXPECT_EQ(shell()->web_contents()->GetLastCommittedURL(), GURL::EmptyGURL()); + EXPECT_EQ(shell()->web_contents()->GetURL(), GURL::EmptyGURL()); EXPECT_EQ(blank_site_instance->GetSiteURL(), GURL::EmptyGURL()); rvh_observers.AddObserverToRVH(blank_rvh); @@ -1275,7 +1269,7 @@ IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, // Wait for the navigation in the new window to finish, if it hasn't. WaitForLoadStop(new_shell->web_contents()); EXPECT_EQ("/files/title1.html", - new_shell->web_contents()->GetLastCommittedURL().path()); + new_shell->web_contents()->GetURL().path()); // Should have the same SiteInstance. EXPECT_EQ(orig_site_instance, new_shell->web_contents()->GetSiteInstance()); @@ -1292,7 +1286,7 @@ IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, // Make sure it ends up at the right page. WaitForLoadStop(shell()->web_contents()); EXPECT_EQ(https_server.GetURL("files/title1.html"), - shell()->web_contents()->GetLastCommittedURL()); + shell()->web_contents()->GetURL()); EXPECT_EQ(new_site_instance, shell()->web_contents()->GetSiteInstance()); } diff --git a/chromium/content/browser/renderer_host/render_widget_host_browsertest.cc b/chromium/content/browser/renderer_host/render_widget_host_browsertest.cc index 2a9ef56a7c9..9f11299b1a6 100644 --- a/chromium/content/browser/renderer_host/render_widget_host_browsertest.cc +++ b/chromium/content/browser/renderer_host/render_widget_host_browsertest.cc @@ -46,14 +46,8 @@ class RenderWidgetHostBrowserTest : public ContentBrowserTest { base::FilePath test_dir_; }; -// Disabled on Windows and CrOS because it is flaky: crbug.com/272379. -#if defined(OS_WIN) || defined(OS_CHROMEOS) -#define MAYBE_GetSnapshotFromRendererTest DISABLED_GetSnapshotFromRendererTest -#else -#define MAYBE_GetSnapshotFromRendererTest GetSnapshotFromRendererTest -#endif IN_PROC_BROWSER_TEST_F(RenderWidgetHostBrowserTest, - MAYBE_GetSnapshotFromRendererTest) { + GetSnapshotFromRendererTest) { base::RunLoop run_loop; NavigateToURL(shell(), GURL(net::FilePathToFileURL( diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_aura.cc b/chromium/content/browser/renderer_host/render_widget_host_view_aura.cc index 8c52017ed59..33ee9524e73 100644 --- a/chromium/content/browser/renderer_host/render_widget_host_view_aura.cc +++ b/chromium/content/browser/renderer_host/render_widget_host_view_aura.cc @@ -2525,32 +2525,6 @@ void RenderWidgetHostViewAura::OnKeyEvent(ui::KeyEvent* event) { host_->Shutdown(); } } else { - // Windows does not have a specific key code for AltGr and sends - // left-Control and right-Alt when the AltGr key is pressed. Also - // Windows translates AltGr modifier to Ctrl+Alt modifier. To be compatible - // with this behavior, we re-write keyboard event from AltGr to Alt + Ctrl - // key event here. - if (event->key_code() == ui::VKEY_ALTGR) { - // Synthesize Ctrl & Alt events. - NativeWebKeyboardEvent ctrl_webkit_event( - event->type(), - false, - ui::VKEY_CONTROL, - event->flags(), - ui::EventTimeForNow().InSecondsF()); - host_->ForwardKeyboardEvent(ctrl_webkit_event); - - NativeWebKeyboardEvent alt_webkit_event( - event->type(), - false, - ui::VKEY_MENU, - event->flags(), - ui::EventTimeForNow().InSecondsF()); - host_->ForwardKeyboardEvent(alt_webkit_event); - event->SetHandled(); - return; - } - // We don't have to communicate with an input method here. if (!event->HasNativeEvent()) { NativeWebKeyboardEvent webkit_event( diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_guest.cc b/chromium/content/browser/renderer_host/render_widget_host_view_guest.cc index 097468fb848..b49ca41054e 100644 --- a/chromium/content/browser/renderer_host/render_widget_host_view_guest.cc +++ b/chromium/content/browser/renderer_host/render_widget_host_view_guest.cc @@ -67,14 +67,22 @@ RenderWidgetHost* RenderWidgetHostViewGuest::GetRenderWidgetHost() const { } void RenderWidgetHostViewGuest::WasShown() { - if (!is_hidden_) + // If the WebContents associated with us showed an interstitial page in the + // beginning, the teardown path might call WasShown() while |host_| is in + // the process of destruction. Avoid calling WasShown below in this case. + // TODO(lazyboy): We shouldn't be showing interstitial pages in guests in the + // first place: http://crbug.com/273089. + // + // |guest_| is NULL during test. + if (!is_hidden_ || (guest_ && guest_->is_in_destruction())) return; is_hidden_ = false; host_->WasShown(); } void RenderWidgetHostViewGuest::WasHidden() { - if (is_hidden_) + // |guest_| is NULL during test. + if (is_hidden_ || (guest_ && guest_->is_in_destruction())) return; is_hidden_ = true; host_->WasHidden(); diff --git a/chromium/content/browser/renderer_host/ui_events_helper.cc b/chromium/content/browser/renderer_host/ui_events_helper.cc index afbbf990176..89242946cab 100644 --- a/chromium/content/browser/renderer_host/ui_events_helper.cc +++ b/chromium/content/browser/renderer_host/ui_events_helper.cc @@ -238,11 +238,6 @@ WebKit::WebGestureEvent MakeWebGestureEventFromUIEvent( int EventFlagsToWebEventModifiers(int flags) { int modifiers = 0; - // Translate AltGr modifier to Ctrl+Alt first. - if (flags & ui::EF_ALTGR_DOWN) { - modifiers |= WebKit::WebInputEvent::ControlKey | - WebKit::WebInputEvent::AltKey; - } if (flags & ui::EF_SHIFT_DOWN) modifiers |= WebKit::WebInputEvent::ShiftKey; if (flags & ui::EF_CONTROL_DOWN) diff --git a/chromium/content/browser/session_history_browsertest.cc b/chromium/content/browser/session_history_browsertest.cc index 966ccc7d941..d0bd95001a8 100644 --- a/chromium/content/browser/session_history_browsertest.cc +++ b/chromium/content/browser/session_history_browsertest.cc @@ -89,7 +89,7 @@ class SessionHistoryTest : public ContentBrowserTest { } GURL GetTabURL() { - return shell()->web_contents()->GetLastCommittedURL(); + return shell()->web_contents()->GetURL(); } GURL GetURL(const std::string file) { diff --git a/chromium/content/browser/speech/speech_recognition_browsertest.cc b/chromium/content/browser/speech/speech_recognition_browsertest.cc index e532bc7a35b..8e4c7a84ed7 100644 --- a/chromium/content/browser/speech/speech_recognition_browsertest.cc +++ b/chromium/content/browser/speech/speech_recognition_browsertest.cc @@ -69,7 +69,7 @@ class SpeechRecognitionBrowserTest : public ContentBrowserTest { // then sets the URL fragment as 'pass' if it received the expected string. LoadAndStartSpeechRecognitionTest(filename); - EXPECT_EQ("pass", shell()->web_contents()->GetLastCommittedURL().ref()); + EXPECT_EQ("pass", shell()->web_contents()->GetURL().ref()); } // ContentBrowserTest methods. diff --git a/chromium/content/browser/streams/stream.cc b/chromium/content/browser/streams/stream.cc index 6026df9e7c7..f5abe0276e8 100644 --- a/chromium/content/browser/streams/stream.cc +++ b/chromium/content/browser/streams/stream.cc @@ -90,9 +90,6 @@ void Stream::Finalize() { Stream::StreamState Stream::ReadRawData(net::IOBuffer* buf, int buf_size, int* bytes_read) { - DCHECK(buf); - DCHECK(bytes_read); - *bytes_read = 0; if (!data_.get()) { data_length_ = 0; diff --git a/chromium/content/browser/streams/stream_unittest.cc b/chromium/content/browser/streams/stream_unittest.cc index c0077b7375b..36add1d649d 100644 --- a/chromium/content/browser/streams/stream_unittest.cc +++ b/chromium/content/browser/streams/stream_unittest.cc @@ -41,7 +41,7 @@ class StreamTest : public testing::Test { class TestStreamReader : public StreamReadObserver { public: - TestStreamReader() : buffer_(new net::GrowableIOBuffer()), completed_(false) { + TestStreamReader() : buffer_(new net::GrowableIOBuffer()) { } virtual ~TestStreamReader() {} @@ -50,22 +50,8 @@ class TestStreamReader : public StreamReadObserver { scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize)); int bytes_read = 0; - while (true) { - Stream::StreamState state = - stream->ReadRawData(buffer.get(), kBufferSize, &bytes_read); - switch (state) { - case Stream::STREAM_HAS_DATA: - // TODO(tyoshino): Move these expectations to the beginning of Read() - // method once Stream::Finalize() is fixed. - EXPECT_FALSE(completed_); - break; - case Stream::STREAM_COMPLETE: - completed_ = true; - return; - case Stream::STREAM_EMPTY: - EXPECT_FALSE(completed_); - return; - } + while (stream->ReadRawData(buffer.get(), kBufferSize, &bytes_read) == + Stream::STREAM_HAS_DATA) { size_t old_capacity = buffer_->capacity(); buffer_->SetCapacity(old_capacity + bytes_read); memcpy(buffer_->StartOfBuffer() + old_capacity, @@ -79,13 +65,8 @@ class TestStreamReader : public StreamReadObserver { scoped_refptr<net::GrowableIOBuffer> buffer() { return buffer_; } - bool completed() const { - return completed_; - } - private: scoped_refptr<net::GrowableIOBuffer> buffer_; - bool completed_; }; class TestStreamWriter : public StreamWriteObserver { @@ -156,38 +137,14 @@ TEST_F(StreamTest, Stream) { scoped_refptr<net::IOBuffer> buffer(NewIOBuffer(kBufferSize)); writer.Write(stream.get(), buffer, kBufferSize); stream->Finalize(); + reader.Read(stream.get()); base::MessageLoop::current()->RunUntilIdle(); - EXPECT_TRUE(reader.completed()); ASSERT_EQ(reader.buffer()->capacity(), kBufferSize); for (int i = 0; i < kBufferSize; i++) EXPECT_EQ(buffer->data()[i], reader.buffer()->data()[i]); } -// Test that even if a reader receives an empty buffer, once TransferData() -// method is called on it with |source_complete| = true, following Read() calls -// on it never returns STREAM_EMPTY. Together with StreamTest.Stream above, this -// guarantees that Reader::Read() call returns only STREAM_HAS_DATA -// or STREAM_COMPLETE in |data_available_callback_| call corresponding to -// Writer::Close(). -TEST_F(StreamTest, ClosedReaderDoesNotReturnStreamEmpty) { - TestStreamReader reader; - TestStreamWriter writer; - - GURL url("blob://stream"); - scoped_refptr<Stream> stream( - new Stream(registry_.get(), &writer, url)); - EXPECT_TRUE(stream->SetReadObserver(&reader)); - - const int kBufferSize = 0; - scoped_refptr<net::IOBuffer> buffer(NewIOBuffer(kBufferSize)); - stream->AddData(buffer, kBufferSize); - stream->Finalize(); - base::MessageLoop::current()->RunUntilIdle(); - EXPECT_TRUE(reader.completed()); - EXPECT_EQ(0, reader.buffer()->capacity()); -} - TEST_F(StreamTest, GetStream) { TestStreamWriter writer; diff --git a/chromium/content/browser/streams/stream_url_request_job.cc b/chromium/content/browser/streams/stream_url_request_job.cc index 0965178de2c..e36c5d49ae6 100644 --- a/chromium/content/browser/streams/stream_url_request_job.cc +++ b/chromium/content/browser/streams/stream_url_request_job.cc @@ -39,37 +39,19 @@ StreamURLRequestJob::~StreamURLRequestJob() { void StreamURLRequestJob::OnDataAvailable(Stream* stream) { // Clear the IO_PENDING status. SetStatus(net::URLRequestStatus()); - // Do nothing if pending_buffer_ is empty, i.e. there's no ReadRawData() - // operation waiting for IO completion. - if (!pending_buffer_.get()) - return; - - // pending_buffer_ is set to the IOBuffer instance provided to ReadRawData() - // by URLRequestJob. - - int bytes_read; - switch (stream_->ReadRawData( - pending_buffer_.get(), pending_buffer_size_, &bytes_read)) { - case Stream::STREAM_HAS_DATA: - DCHECK_GT(bytes_read, 0); - break; - case Stream::STREAM_COMPLETE: - // Ensure this. Calling NotifyReadComplete call with 0 signals - // completion. - bytes_read = 0; - break; - case Stream::STREAM_EMPTY: - NOTREACHED(); - break; + if (pending_buffer_.get()) { + int bytes_read; + stream_->ReadRawData( + pending_buffer_.get(), pending_buffer_size_, &bytes_read); + + // Clear the buffers before notifying the read is complete, so that it is + // safe for the observer to read. + pending_buffer_ = NULL; + pending_buffer_size_ = 0; + + total_bytes_read_ += bytes_read; + NotifyReadComplete(bytes_read); } - - // Clear the buffers before notifying the read is complete, so that it is - // safe for the observer to read. - pending_buffer_ = NULL; - pending_buffer_size_ = 0; - - total_bytes_read_ += bytes_read; - NotifyReadComplete(bytes_read); } // net::URLRequestJob methods. @@ -92,7 +74,6 @@ bool StreamURLRequestJob::ReadRawData(net::IOBuffer* buf, if (request_failed_) return true; - DCHECK(buf); DCHECK(bytes_read); int to_read = buf_size; if (max_range_ && to_read) { @@ -186,6 +167,7 @@ void StreamURLRequestJob::NotifyFailure(int error_code) { // TODO(zork): Share these with BlobURLRequestJob. net::HttpStatusCode status_code = net::HTTP_INTERNAL_SERVER_ERROR; + std::string status_txt; switch (error_code) { case net::ERR_ACCESS_DENIED: status_code = net::HTTP_FORBIDDEN; diff --git a/chromium/content/browser/web_contents/navigation_controller_impl.cc b/chromium/content/browser/web_contents/navigation_controller_impl.cc index c3e9140b48f..2c0596d9c83 100644 --- a/chromium/content/browser/web_contents/navigation_controller_impl.cc +++ b/chromium/content/browser/web_contents/navigation_controller_impl.cc @@ -1623,12 +1623,15 @@ void NavigationControllerImpl::FinishRestore(int selected_index, } void NavigationControllerImpl::DiscardNonCommittedEntriesInternal() { + DiscardPendingEntry(); + DiscardTransientEntry(); +} + +void NavigationControllerImpl::DiscardPendingEntry() { if (pending_entry_index_ == -1) delete pending_entry_; pending_entry_ = NULL; pending_entry_index_ = -1; - - DiscardTransientEntry(); } void NavigationControllerImpl::DiscardTransientEntry() { diff --git a/chromium/content/browser/web_contents/navigation_controller_impl.h b/chromium/content/browser/web_contents/navigation_controller_impl.h index bef3be2202f..2f0d71ea966 100644 --- a/chromium/content/browser/web_contents/navigation_controller_impl.h +++ b/chromium/content/browser/web_contents/navigation_controller_impl.h @@ -289,10 +289,13 @@ class CONTENT_EXPORT NavigationControllerImpl // Removes the entry at |index|, as long as it is not the current entry. void RemoveEntryAtIndexInternal(int index); - // Discards the pending and transient entries. + // Discards both the pending and transient entries. void DiscardNonCommittedEntriesInternal(); - // Discards the transient entry. + // Discards only the pending entry. + void DiscardPendingEntry(); + + // Discards only the transient entry. void DiscardTransientEntry(); // If we have the maximum number of entries, remove the oldest one in diff --git a/chromium/content/browser/web_contents/navigation_controller_impl_unittest.cc b/chromium/content/browser/web_contents/navigation_controller_impl_unittest.cc index 7a0b03b2bf0..df6a47c1b13 100644 --- a/chromium/content/browser/web_contents/navigation_controller_impl_unittest.cc +++ b/chromium/content/browser/web_contents/navigation_controller_impl_unittest.cc @@ -1008,10 +1008,10 @@ TEST_F(NavigationControllerTest, LoadURL_RedirectAbortDoesntShowPendingURL) { ViewHostMsg_DidFailProvisionalLoadWithError(0, // routing_id params)); - // This should not clear the pending entry or notify of a navigation state - // change. + // Because the pending entry is renderer initiated and not visible, we + // clear it when it fails. EXPECT_EQ(-1, controller.GetPendingEntryIndex()); - EXPECT_TRUE(controller.GetPendingEntry()); + EXPECT_FALSE(controller.GetPendingEntry()); EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); EXPECT_EQ(0, delegate->navigation_state_change_count()); diff --git a/chromium/content/browser/web_contents/touch_editable_impl_aura.cc b/chromium/content/browser/web_contents/touch_editable_impl_aura.cc index fb430d092e0..d38f5f5c7f6 100644 --- a/chromium/content/browser/web_contents/touch_editable_impl_aura.cc +++ b/chromium/content/browser/web_contents/touch_editable_impl_aura.cc @@ -53,7 +53,7 @@ void TouchEditableImplAura::UpdateEditingController() { // there is non-zero selection on the page. And the current event is a // gesture event (we dont want to show handles if the user is selecting // using mouse or keyboard). - if (selection_gesture_in_process_ && + if (selection_gesture_in_process_ && !scroll_in_progress_ && selection_anchor_rect_ != selection_focus_rect_) StartTouchEditing(); @@ -66,6 +66,29 @@ void TouchEditableImplAura::UpdateEditingController() { } } +void TouchEditableImplAura::OverscrollStarted() { + overscroll_in_progress_ = true; +} + +void TouchEditableImplAura::OverscrollCompleted() { + // We might receive multiple OverscrollStarted() and OverscrollCompleted() + // during the same scroll session (for example, when the scroll direction + // changes). We want to show the handles only when: + // 1. Overscroll has completed + // 2. Scrolling session is over, i.e. we have received ET_GESTURE_SCROLL_END. + // 3. If we had hidden the handles when scrolling started + // 4. If there is still a need to show handles (there is a non-empty selection + // or non-NONE |text_input_type_|) + if (overscroll_in_progress_ && !scroll_in_progress_ && + handles_hidden_due_to_scroll_ && + (selection_anchor_rect_ != selection_focus_rect_ || + text_input_type_ != ui::TEXT_INPUT_TYPE_NONE)) { + StartTouchEditing(); + UpdateEditingController(); + } + overscroll_in_progress_ = false; +} + //////////////////////////////////////////////////////////////////////////////// // TouchEditableImplAura, RenderWidgetHostViewAura::TouchEditingClient // implementation: @@ -145,18 +168,24 @@ bool TouchEditableImplAura::HandleInputEvent(const ui::Event* event) { // when scrolling ends. So we set |handles_hidden_due_to_scroll_| so that // we can re-start touch editing when we call |UpdateEditingController()| // on scroll end gesture. + scroll_in_progress_ = true; handles_hidden_due_to_scroll_ = false; if (touch_selection_controller_) handles_hidden_due_to_scroll_ = true; EndTouchEditing(); break; case ui::ET_GESTURE_SCROLL_END: - if (handles_hidden_due_to_scroll_ && + // Scroll has ended, but we might still be in overscroll animation. + if (handles_hidden_due_to_scroll_ && !overscroll_in_progress_ && (selection_anchor_rect_ != selection_focus_rect_ || text_input_type_ != ui::TEXT_INPUT_TYPE_NONE)) { StartTouchEditing(); UpdateEditingController(); } + // fall through to reset |scroll_in_progress_|. + case ui::ET_SCROLL_FLING_START: + selection_gesture_in_process_ = false; + scroll_in_progress_ = false; break; default: break; @@ -330,6 +359,8 @@ TouchEditableImplAura::TouchEditableImplAura() rwhva_(NULL), selection_gesture_in_process_(false), handles_hidden_due_to_scroll_(false), + scroll_in_progress_(false), + overscroll_in_progress_(false), is_tap_on_focused_textfield_(false) { } @@ -338,7 +369,11 @@ void TouchEditableImplAura::Cleanup() { rwhva_->set_touch_editing_client(NULL); rwhva_ = NULL; } + text_input_type_ = ui::TEXT_INPUT_TYPE_NONE; touch_selection_controller_.reset(); + handles_hidden_due_to_scroll_ = false; + scroll_in_progress_ = false; + overscroll_in_progress_ = false; } } // namespace content diff --git a/chromium/content/browser/web_contents/touch_editable_impl_aura.h b/chromium/content/browser/web_contents/touch_editable_impl_aura.h index c31d86ae7a7..7f1ea845512 100644 --- a/chromium/content/browser/web_contents/touch_editable_impl_aura.h +++ b/chromium/content/browser/web_contents/touch_editable_impl_aura.h @@ -37,6 +37,9 @@ class CONTENT_EXPORT TouchEditableImplAura // depending on the current selection and cursor state. void UpdateEditingController(); + void OverscrollStarted(); + void OverscrollCompleted(); + // Overridden from RenderWidgetHostViewAura::TouchEditingClient. virtual void StartTouchEditing() OVERRIDE; virtual void EndTouchEditing() OVERRIDE; @@ -87,8 +90,16 @@ class CONTENT_EXPORT TouchEditableImplAura // change in selection (long press, double tap or triple tap). bool selection_gesture_in_process_; + // Set to true if handles are hidden when user is scrolling. Used to determine + // whether to re-show handles after a scrolling session. bool handles_hidden_due_to_scroll_; + // Keeps track of when the user is scrolling. + bool scroll_in_progress_; + + // Set to true when the page starts an overscroll. + bool overscroll_in_progress_; + // Used to track if the current tap gesture is on a focused textfield. bool is_tap_on_focused_textfield_; diff --git a/chromium/content/browser/web_contents/web_contents_drag_win.cc b/chromium/content/browser/web_contents/web_contents_drag_win.cc index cb24210c3b9..68e27884475 100644 --- a/chromium/content/browser/web_contents/web_contents_drag_win.cc +++ b/chromium/content/browser/web_contents/web_contents_drag_win.cc @@ -163,7 +163,7 @@ void WebContentsDragWin::StartDragging(const DropData& drop_data, drag_source_ = new WebDragSource(source_window_, web_contents_); - const GURL& page_url = web_contents_->GetLastCommittedURL(); + const GURL& page_url = web_contents_->GetURL(); const std::string& page_encoding = web_contents_->GetEncoding(); // If it is not drag-out, do the drag-and-drop in the current UI thread. diff --git a/chromium/content/browser/web_contents/web_contents_impl.cc b/chromium/content/browser/web_contents/web_contents_impl.cc index 157a17d6a8e..2d19b65e479 100644 --- a/chromium/content/browser/web_contents/web_contents_impl.cc +++ b/chromium/content/browser/web_contents/web_contents_impl.cc @@ -1422,6 +1422,23 @@ void WebContentsImpl::CreateNewWindow( int main_frame_route_id, const ViewHostMsg_CreateWindow_Params& params, SessionStorageNamespace* session_storage_namespace) { + if (delegate_ && + !delegate_->ShouldCreateWebContents(this, + route_id, + params.window_container_type, + params.frame_name, + params.target_url, + params.referrer, + params.disposition, + params.features, + params.user_gesture, + params.opener_suppressed)) { + GetRenderViewHost()->GetProcess()->ResumeRequestsForView(route_id); + GetRenderViewHost()->GetProcess()->ResumeRequestsForView( + main_frame_route_id); + return; + } + // We usually create the new window in the same BrowsingInstance (group of // script-related windows), by passing in the current SiteInstance. However, // if the opener is being suppressed (in a non-guest), we create a new @@ -1433,6 +1450,12 @@ void WebContentsImpl::CreateNewWindow( SiteInstance::CreateForURL(GetBrowserContext(), params.target_url) : GetSiteInstance(); + // Create the new web contents. This will automatically create the new + // WebContentsView. In the future, we may want to create the view separately. + WebContentsImpl* new_contents = + new WebContentsImpl(GetBrowserContext(), + params.opener_suppressed ? NULL : this); + // We must assign the SessionStorageNamespace before calling Init(). // // http://crbug.com/142685 @@ -1447,27 +1470,6 @@ void WebContentsImpl::CreateNewWindow( SessionStorageNamespaceImpl* session_storage_namespace_impl = static_cast<SessionStorageNamespaceImpl*>(session_storage_namespace); CHECK(session_storage_namespace_impl->IsFromContext(dom_storage_context)); - - if (delegate_ && - !delegate_->ShouldCreateWebContents(this, - route_id, - params.window_container_type, - params.frame_name, - params.target_url, - partition_id, - session_storage_namespace)) { - GetRenderViewHost()->GetProcess()->ResumeRequestsForView(route_id); - GetRenderViewHost()->GetProcess()->ResumeRequestsForView( - main_frame_route_id); - return; - } - - // Create the new web contents. This will automatically create the new - // WebContentsView. In the future, we may want to create the view separately. - WebContentsImpl* new_contents = - new WebContentsImpl(GetBrowserContext(), - params.opener_suppressed ? NULL : this); - new_contents->GetController().SetSessionStorageNamespace( partition_id, session_storage_namespace); @@ -2241,13 +2243,21 @@ void WebContentsImpl::DidFailProvisionalLoadWithError( return; } - // Do not clear the pending entry if one exists, so that the user's typed - // URL is not lost when a navigation fails or is aborted. We'll allow - // the view to clear the pending entry and typed URL if the user requests. - render_manager_.RendererAbortedProvisionalLoad(render_view_host); } + // Do not usually clear the pending entry if one exists, so that the user's + // typed URL is not lost when a navigation fails or is aborted. However, in + // cases that we don't show the pending entry (e.g., renderer-initiated + // navigations in an existing tab), we don't keep it around. That prevents + // spoofs on in-page navigations that don't go through + // DidStartProvisionalLoadForFrame. + // In general, we allow the view to clear the pending entry and typed URL if + // the user requests (e.g., hitting Escape with focus in the address bar). + // Note: don't touch the transient entry, since an interstitial may exist. + if (controller_.GetPendingEntry() != controller_.GetVisibleEntry()) + controller_.DiscardPendingEntry(); + FOR_EACH_OBSERVER(WebContentsObserver, observers_, DidFailProvisionalLoad(params.frame_id, @@ -2863,16 +2873,14 @@ void WebContentsImpl::RenderViewCreated(RenderViewHost* render_view_host) { NOTIFICATION_WEB_CONTENTS_RENDER_VIEW_HOST_CREATED, Source<WebContents>(this), Details<RenderViewHost>(render_view_host)); - NavigationEntry* entry = controller_.GetActiveEntry(); - if (!entry) - return; // When we're creating views, we're still doing initial setup, so we always // use the pending Web UI rather than any possibly existing committed one. if (render_manager_.pending_web_ui()) render_manager_.pending_web_ui()->RenderViewCreated(render_view_host); - if (entry->IsViewSourceMode()) { + NavigationEntry* entry = controller_.GetActiveEntry(); + if (entry && entry->IsViewSourceMode()) { // Put the renderer in view source mode. render_view_host->Send( new ViewMsg_EnableViewSourceMode(render_view_host->GetRoutingID())); @@ -3652,6 +3660,13 @@ bool WebContentsImpl::CreateRenderViewForRenderManager( return true; } +#if defined(OS_ANDROID) +bool WebContentsImpl::CreateRenderViewForInitialEmptyDocument() { + return CreateRenderViewForRenderManager(GetRenderViewHost(), + MSG_ROUTING_NONE); +} +#endif + void WebContentsImpl::OnDialogClosed(RenderViewHost* rvh, IPC::Message* reply_msg, bool success, diff --git a/chromium/content/browser/web_contents/web_contents_impl.h b/chromium/content/browser/web_contents/web_contents_impl.h index 21ec675da5f..a5eaf7ddcbe 100644 --- a/chromium/content/browser/web_contents/web_contents_impl.h +++ b/chromium/content/browser/web_contents/web_contents_impl.h @@ -153,6 +153,13 @@ class CONTENT_EXPORT WebContentsImpl JavaBridgeDispatcherHostManager* java_bridge_dispatcher_host_manager() const { return java_bridge_dispatcher_host_manager_.get(); } + + // In Android WebView, the RenderView needs created even there is no + // navigation entry, this allows Android WebViews to use + // javascript: URLs that load into the DOMWindow before the first page + // load. This is not safe to do in any context that a web page could get a + // reference to the DOMWindow before the first page load. + bool CreateRenderViewForInitialEmptyDocument(); #endif // Expose the render manager for testing. diff --git a/chromium/content/browser/web_contents/web_contents_impl_browsertest.cc b/chromium/content/browser/web_contents/web_contents_impl_browsertest.cc index 0cb9fe258ea..5ea20a6affa 100644 --- a/chromium/content/browser/web_contents/web_contents_impl_browsertest.cc +++ b/chromium/content/browser/web_contents/web_contents_impl_browsertest.cc @@ -119,6 +119,33 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, EXPECT_EQ(&shell()->web_contents()->GetController(), load_observer.controller_); } +// Test that a renderer-initiated navigation to an invalid URL does not leave +// around a pending entry that could be used in a URL spoof. We test this in +// a browser test because our unit test framework incorrectly calls +// DidStartProvisionalLoadForFrame for in-page navigations. +// See http://crbug.com/280512. +IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, + ClearNonVisiblePendingOnFail) { + ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); + + NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html")); + + // Navigate to an invalid URL and make sure it doesn't leave a pending entry. + LoadStopNotificationObserver load_observer1( + &shell()->web_contents()->GetController()); + ASSERT_TRUE(ExecuteScript(shell()->web_contents(), + "window.location.href=\"nonexistent:12121\";")); + load_observer1.Wait(); + EXPECT_FALSE(shell()->web_contents()->GetController().GetPendingEntry()); + + LoadStopNotificationObserver load_observer2( + &shell()->web_contents()->GetController()); + ASSERT_TRUE(ExecuteScript(shell()->web_contents(), + "window.location.href=\"#foo\";")); + load_observer2.Wait(); + EXPECT_EQ(embedded_test_server()->GetURL("/title1.html#foo"), + shell()->web_contents()->GetVisibleURL()); +} // Test that the browser receives the proper frame attach/detach messages from // the renderer and builds proper frame tree. diff --git a/chromium/content/browser/web_contents/web_contents_view_aura.cc b/chromium/content/browser/web_contents/web_contents_view_aura.cc index 043efca119a..013edc7fe3e 100644 --- a/chromium/content/browser/web_contents/web_contents_view_aura.cc +++ b/chromium/content/browser/web_contents/web_contents_view_aura.cc @@ -1362,6 +1362,9 @@ void WebContentsViewAura::OnOverscrollModeChange(OverscrollMode old_mode, // Reset any in-progress overscroll animation first. ResetOverscrollTransform(); + if (new_mode != OVERSCROLL_NONE && touch_editable_) + touch_editable_->OverscrollStarted(); + if (new_mode == OVERSCROLL_NONE || !GetContentNativeView() || ((new_mode == OVERSCROLL_EAST || new_mode == OVERSCROLL_WEST) && @@ -1402,6 +1405,9 @@ void WebContentsViewAura::OnImplicitAnimationsCompleted() { completed_overscroll_gesture_)) { PrepareOverscrollNavigationOverlay(); web_contents_->GetController().GoBack(); + } else { + if (touch_editable_) + touch_editable_->OverscrollCompleted(); } aura::Window* content = GetContentNativeView(); diff --git a/chromium/content/browser/web_contents/web_drag_source_mac.mm b/chromium/content/browser/web_contents/web_drag_source_mac.mm index 6a31fe26c46..0b44fd47930 100644 --- a/chromium/content/browser/web_contents/web_drag_source_mac.mm +++ b/chromium/content/browser/web_contents/web_drag_source_mac.mm @@ -10,6 +10,7 @@ #include "base/files/file_path.h" #include "base/mac/mac_logging.h" #include "base/mac/mac_util.h" +#include "base/mac/scoped_aedesc.h" #include "base/pickle.h" #include "base/strings/string_util.h" #include "base/strings/sys_string_conversions.h" @@ -120,6 +121,87 @@ NSString* GetDropLocation(NSPasteboard* pboard) { return drop_path; } +void SelectFileInFinder(const base::FilePath& file_path) { + DCHECK([NSThread isMainThread]); + + // Create the target of this AppleEvent, the Finder. + base::mac::ScopedAEDesc<AEAddressDesc> address; + const OSType finder_creator_code = 'MACS'; + OSErr status = AECreateDesc(typeApplSignature, // type + &finder_creator_code, // data + sizeof(finder_creator_code), // dataSize + address.OutPointer()); // result + if (status != noErr) { + OSSTATUS_LOG(WARNING, status) << "Could not create SelectFile() AE target"; + return; + } + + // Build the AppleEvent data structure that instructs Finder to select files. + base::mac::ScopedAEDesc<AppleEvent> the_event; + status = AECreateAppleEvent(kAEMiscStandards, // theAEEventClass + kAESelect, // theAEEventID + address, // target + kAutoGenerateReturnID, // returnID + kAnyTransactionID, // transactionID + the_event.OutPointer()); // result + if (status != noErr) { + OSSTATUS_LOG(WARNING, status) << "Could not create SelectFile() AE event"; + return; + } + + // Create the list of files (only ever one) to select. + base::mac::ScopedAEDesc<AEDescList> file_list; + status = AECreateList(NULL, // factoringPtr + 0, // factoredSize + false, // isRecord + file_list.OutPointer()); // resultList + if (status != noErr) { + OSSTATUS_LOG(WARNING, status) + << "Could not create SelectFile() AE file list"; + return; + } + + // Add the single path to the file list. + NSURL* url = [NSURL fileURLWithPath:SysUTF8ToNSString(file_path.value())]; + base::ScopedCFTypeRef<CFDataRef> url_data( + CFURLCreateData(kCFAllocatorDefault, base::mac::NSToCFCast(url), + kCFStringEncodingUTF8, true)); + status = AEPutPtr(file_list.OutPointer(), // theAEDescList + 0, // index + typeFileURL, // typeCode + CFDataGetBytePtr(url_data), // dataPtr + CFDataGetLength(url_data)); // dataSize + if (status != noErr) { + OSSTATUS_LOG(WARNING, status) + << "Could not add file path to AE list in SelectFile()"; + return; + } + + // Attach the file list to the AppleEvent. + status = AEPutParamDesc(the_event.OutPointer(), // theAppleEvent + keyDirectObject, // theAEKeyword + file_list); // theAEDesc + if (status != noErr) { + OSSTATUS_LOG(WARNING, status) + << "Could not put the AE file list the path in SelectFile()"; + return; + } + + // Send the actual event. Do not care about the reply. + base::mac::ScopedAEDesc<AppleEvent> reply; + status = AESend(the_event, // theAppleEvent + reply.OutPointer(), // reply + kAENoReply + kAEAlwaysInteract, // sendMode + kAENormalPriority, // sendPriority + kAEDefaultTimeout, // timeOutInTicks + NULL, // idleProc + NULL); // filterProc + if (status != noErr) { + OSSTATUS_LOG(WARNING, status) + << "Could not send AE to Finder in SelectFile()"; + } +} + } // namespace @@ -383,8 +465,7 @@ NSString* GetDropLocation(NSPasteboard* pboard) { filePath, fileStream.Pass(), downloadURL_, - content::Referrer(contents_->GetLastCommittedURL(), - dropData_->referrer_policy), + content::Referrer(contents_->GetURL(), dropData_->referrer_policy), contents_->GetEncoding(), contents_)); @@ -399,6 +480,7 @@ NSString* GetDropLocation(NSPasteboard* pboard) { *dropData_, base::Passed(&fileStream))); } + SelectFileInFinder(filePath); } - (void)fillPasteboard { diff --git a/chromium/content/child/fileapi/webfilesystem_impl.cc b/chromium/content/child/fileapi/webfilesystem_impl.cc index ccb902e72f0..052bce489c9 100644 --- a/chromium/content/child/fileapi/webfilesystem_impl.cc +++ b/chromium/content/child/fileapi/webfilesystem_impl.cc @@ -9,11 +9,11 @@ #include "base/lazy_instance.h" #include "base/logging.h" #include "base/message_loop/message_loop_proxy.h" -#include "base/strings/utf_string_conversions.h" #include "base/synchronization/waitable_event.h" #include "base/threading/thread_local.h" #include "content/child/child_thread.h" #include "content/child/fileapi/file_system_dispatcher.h" +#include "content/child/fileapi/webfilesystem_callback_adapters.h" #include "content/child/fileapi/webfilewriter_impl.h" #include "content/common/fileapi/file_system_messages.h" #include "third_party/WebKit/public/platform/WebFileInfo.h" @@ -43,9 +43,6 @@ class CallbacksMap; base::LazyInstance<base::ThreadLocalPointer<CallbacksMap> >::Leaky g_callbacks_map_tls = LAZY_INSTANCE_INITIALIZER; -base::LazyInstance<base::ThreadLocalPointer<WebFileSystemImpl> >::Leaky - g_webfilesystem_tls = LAZY_INSTANCE_INITIALIZER; - // TODO(kinuko): Integrate this into WebFileSystemImpl when blink side // becomes ready to make WebFileSystemImpl thread-local. class CallbacksMap : public WorkerTaskRunner::Observer { @@ -196,21 +193,6 @@ void CallbackFileSystemCallbacks( base::Bind(&RunCallbacks<Method, Params>, callbacks_id, method, params)); } -//----------------------------------------------------------------------------- -// Callback adapters. Callbacks must be called on the original calling thread, -// so these callback adapters relay back the results to the calling thread -// if necessary. - -void OpenFileSystemCallbackAdapter( - int thread_id, int callbacks_id, - WaitableCallbackResults* waitable_results, - const std::string& name, const GURL& root) { - CallbackFileSystemCallbacks( - thread_id, callbacks_id, waitable_results, - &WebFileSystemCallbacks::didOpenFileSystem, - MakeTuple(UTF8ToUTF16(name), root)); -} - void StatusCallbackAdapter(int thread_id, int callbacks_id, WaitableCallbackResults* waitable_results, base::PlatformFileError error) { @@ -330,77 +312,11 @@ void CreateSnapshotFileCallbackAdapter( } // namespace -//----------------------------------------------------------------------------- -// WebFileSystemImpl - -WebFileSystemImpl* WebFileSystemImpl::ThreadSpecificInstance( - base::MessageLoopProxy* main_thread_loop) { - if (g_webfilesystem_tls.Pointer()->Get()) - return g_webfilesystem_tls.Pointer()->Get(); - WebFileSystemImpl* filesystem = new WebFileSystemImpl(main_thread_loop); - if (WorkerTaskRunner::Instance()->CurrentWorkerId()) - WorkerTaskRunner::Instance()->AddStopObserver(filesystem); - return filesystem; -} - -void WebFileSystemImpl::DeleteThreadSpecificInstance() { - DCHECK(!WorkerTaskRunner::Instance()->CurrentWorkerId()); - if (g_webfilesystem_tls.Pointer()->Get()) - delete g_webfilesystem_tls.Pointer()->Get(); +WebFileSystemImpl::~WebFileSystemImpl() { } WebFileSystemImpl::WebFileSystemImpl(base::MessageLoopProxy* main_thread_loop) : main_thread_loop_(main_thread_loop) { - g_webfilesystem_tls.Pointer()->Set(this); -} - -WebFileSystemImpl::~WebFileSystemImpl() { - g_webfilesystem_tls.Pointer()->Set(NULL); -} - -void WebFileSystemImpl::OnWorkerRunLoopStopped() { - delete this; -} - -void WebFileSystemImpl::openFileSystem( - const WebKit::WebURL& storage_partition, - WebKit::WebFileSystemType type, - bool create, - WebKit::WebFileSystemCallbacks* callbacks) { - int callbacks_id = CallbacksMap::GetOrCreate()->RegisterCallbacks(callbacks); - WaitableCallbackResults* waitable_results = - WaitableCallbackResults::MaybeCreate(callbacks); - CallDispatcherOnMainThread( - main_thread_loop_.get(), - &FileSystemDispatcher::OpenFileSystem, - MakeTuple(GURL(storage_partition), - static_cast<fileapi::FileSystemType>(type), - 0 /* size (not used) */, create, - base::Bind(&OpenFileSystemCallbackAdapter, - CurrentWorkerId(), callbacks_id, - base::Unretained(waitable_results)), - base::Bind(&StatusCallbackAdapter, - CurrentWorkerId(), callbacks_id, - base::Unretained(waitable_results))), - make_scoped_ptr(waitable_results)); -} - -void WebFileSystemImpl::deleteFileSystem( - const WebKit::WebURL& storage_partition, - WebKit::WebFileSystemType type, - WebKit::WebFileSystemCallbacks* callbacks) { - int callbacks_id = CallbacksMap::GetOrCreate()->RegisterCallbacks(callbacks); - WaitableCallbackResults* waitable_results = - WaitableCallbackResults::MaybeCreate(callbacks); - CallDispatcherOnMainThread( - main_thread_loop_.get(), - &FileSystemDispatcher::DeleteFileSystem, - MakeTuple(GURL(storage_partition), - static_cast<fileapi::FileSystemType>(type), - base::Bind(&StatusCallbackAdapter, - CurrentWorkerId(), callbacks_id, - base::Unretained(waitable_results))), - make_scoped_ptr(waitable_results)); } void WebFileSystemImpl::move( diff --git a/chromium/content/child/fileapi/webfilesystem_impl.h b/chromium/content/child/fileapi/webfilesystem_impl.h index eec16e194cd..d9a25840cf1 100644 --- a/chromium/content/child/fileapi/webfilesystem_impl.h +++ b/chromium/content/child/fileapi/webfilesystem_impl.h @@ -9,7 +9,6 @@ #include "base/compiler_specific.h" #include "base/memory/ref_counted.h" #include "third_party/WebKit/public/platform/WebFileSystem.h" -#include "webkit/child/worker_task_runner.h" namespace base { class MessageLoopProxy; @@ -23,35 +22,12 @@ class WebFileWriterClient; namespace content { -class WebFileSystemImpl - : public WebKit::WebFileSystem, - public webkit_glue::WorkerTaskRunner::Observer { +class WebFileSystemImpl : public WebKit::WebFileSystem { public: - // Returns thread-specific instance. - static WebFileSystemImpl* ThreadSpecificInstance( - base::MessageLoopProxy* main_thread_loop); - - // Deletes thread-specific instance (if exists). For workers it deletes - // itself in OnWorkerRunLoopStopped(), but for an instance created on the - // main thread this method must be called. - static void DeleteThreadSpecificInstance(); - explicit WebFileSystemImpl(base::MessageLoopProxy* main_thread_loop); virtual ~WebFileSystemImpl(); - // webkit_glue::WorkerTaskRunner::Observer implementation. - virtual void OnWorkerRunLoopStopped() OVERRIDE; - // WebFileSystem implementation. - virtual void openFileSystem( - const WebKit::WebURL& storage_partition, - const WebKit::WebFileSystemType type, - bool create, - WebKit::WebFileSystemCallbacks*); - virtual void deleteFileSystem( - const WebKit::WebURL& storage_partition, - const WebKit::WebFileSystemType type, - WebKit::WebFileSystemCallbacks*); virtual void move( const WebKit::WebURL& src_path, const WebKit::WebURL& dest_path, diff --git a/chromium/content/child/fileapi/webfilewriter_base.cc b/chromium/content/child/fileapi/webfilewriter_base.cc deleted file mode 100644 index fd0a2070c49..00000000000 --- a/chromium/content/child/fileapi/webfilewriter_base.cc +++ /dev/null @@ -1,152 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/child/fileapi/webfilewriter_base.h" - -#include "base/logging.h" -#include "third_party/WebKit/public/platform/WebURL.h" -#include "third_party/WebKit/public/web/WebFileError.h" -#include "third_party/WebKit/public/web/WebFileWriterClient.h" -#include "webkit/common/fileapi/file_system_util.h" - -using fileapi::PlatformFileErrorToWebFileError; - -namespace content { - -WebFileWriterBase::WebFileWriterBase(const GURL& path, - WebKit::WebFileWriterClient* client) - : path_(path), - client_(client), - operation_(kOperationNone), - cancel_state_(kCancelNotInProgress) {} - -WebFileWriterBase::~WebFileWriterBase() {} - -void WebFileWriterBase::truncate(long long length) { - DCHECK(kOperationNone == operation_); - DCHECK(kCancelNotInProgress == cancel_state_); - operation_ = kOperationTruncate; - DoTruncate(path_, length); -} - -void WebFileWriterBase::write(long long position, - const WebKit::WebURL& blob_url) { - DCHECK(kOperationNone == operation_); - DCHECK(kCancelNotInProgress == cancel_state_); - operation_ = kOperationWrite; - DoWrite(path_, blob_url, position); -} - -// When we cancel a write/truncate, we always get back the result of the write -// before the result of the cancel, no matter what happens. -// So we'll get back either -// success [of the write/truncate, in a DidWrite(XXX, true)/DidSucceed() call] -// followed by failure [of the cancel]; or -// failure [of the write, either from cancel or other reasons] followed by -// the result of the cancel. -// In the write case, there could also be queued up non-terminal DidWrite calls -// before any of that comes back, but there will always be a terminal write -// response [success or failure] after them, followed by the cancel result, so -// we can ignore non-terminal write responses, take the terminal write success -// or the first failure as the last write response, then know that the next -// thing to come back is the cancel response. We only notify the -// AsyncFileWriterClient when it's all over. -void WebFileWriterBase::cancel() { - // Check for the cancel passing the previous operation's return in-flight. - if (kOperationWrite != operation_ && kOperationTruncate != operation_) - return; - if (kCancelNotInProgress != cancel_state_) - return; - cancel_state_ = kCancelSent; - DoCancel(); -} - -void WebFileWriterBase::DidFinish(base::PlatformFileError error_code) { - if (error_code == base::PLATFORM_FILE_OK) - DidSucceed(); - else - DidFail(error_code); -} - -void WebFileWriterBase::DidWrite(int64 bytes, bool complete) { - DCHECK(kOperationWrite == operation_); - switch (cancel_state_) { - case kCancelNotInProgress: - if (complete) - operation_ = kOperationNone; - client_->didWrite(bytes, complete); - break; - case kCancelSent: - // This is the success call of the write, which we'll eat, even though - // it succeeded before the cancel got there. We accepted the cancel call, - // so the write will eventually return an error. - if (complete) - cancel_state_ = kCancelReceivedWriteResponse; - break; - case kCancelReceivedWriteResponse: - default: - NOTREACHED(); - } -} - -void WebFileWriterBase::DidSucceed() { - // Write never gets a DidSucceed call, so this is either a cancel or truncate - // response. - switch (cancel_state_) { - case kCancelNotInProgress: - // A truncate succeeded, with no complications. - DCHECK(kOperationTruncate == operation_); - operation_ = kOperationNone; - client_->didTruncate(); - break; - case kCancelSent: - DCHECK(kOperationTruncate == operation_); - // This is the success call of the truncate, which we'll eat, even though - // it succeeded before the cancel got there. We accepted the cancel call, - // so the truncate will eventually return an error. - cancel_state_ = kCancelReceivedWriteResponse; - break; - case kCancelReceivedWriteResponse: - // This is the success of the cancel operation. - FinishCancel(); - break; - default: - NOTREACHED(); - } -} - -void WebFileWriterBase::DidFail(base::PlatformFileError error_code) { - DCHECK(kOperationNone != operation_); - switch (cancel_state_) { - case kCancelNotInProgress: - // A write or truncate failed. - operation_ = kOperationNone; - client_->didFail(PlatformFileErrorToWebFileError(error_code)); - break; - case kCancelSent: - // This is the failure of a write or truncate; the next message should be - // the result of the cancel. We don't assume that it'll be a success, as - // the write/truncate could have failed for other reasons. - cancel_state_ = kCancelReceivedWriteResponse; - break; - case kCancelReceivedWriteResponse: - // The cancel reported failure, meaning that the write or truncate - // finished before the cancel got there. But we suppressed the - // write/truncate's response, and will now report that it was cancelled. - FinishCancel(); - break; - default: - NOTREACHED(); - } -} - -void WebFileWriterBase::FinishCancel() { - DCHECK(kCancelReceivedWriteResponse == cancel_state_); - DCHECK(kOperationNone != operation_); - cancel_state_ = kCancelNotInProgress; - operation_ = kOperationNone; - client_->didFail(WebKit::WebFileErrorAbort); -} - -} // namespace content diff --git a/chromium/content/child/fileapi/webfilewriter_base.h b/chromium/content/child/fileapi/webfilewriter_base.h deleted file mode 100644 index d3873dc1fb6..00000000000 --- a/chromium/content/child/fileapi/webfilewriter_base.h +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_CHILD_FILEAPI_WEBFILEWRITER_BASE_H_ -#define CONTENT_CHILD_FILEAPI_WEBFILEWRITER_BASE_H_ - -#include "base/platform_file.h" -#include "content/common/content_export.h" -#include "third_party/WebKit/public/web/WebFileWriter.h" -#include "url/gurl.h" - -namespace WebKit { -class WebFileWriterClient; -class WebURL; -} - -namespace content { - -class CONTENT_EXPORT WebFileWriterBase - : public NON_EXPORTED_BASE(WebKit::WebFileWriter) { - public: - WebFileWriterBase(const GURL& path, WebKit::WebFileWriterClient* client); - virtual ~WebFileWriterBase(); - - // WebFileWriter implementation - virtual void truncate(long long length); - virtual void write(long long position, const WebKit::WebURL& blobURL); - virtual void cancel(); - - protected: - // This calls DidSucceed() or DidFail() based on the value of |error_code|. - void DidFinish(base::PlatformFileError error_code); - - void DidWrite(int64 bytes, bool complete); - void DidSucceed(); - void DidFail(base::PlatformFileError error_code); - - // Derived classes must provide these methods to asynchronously perform - // the requested operation, and they must call the appropiate DidSomething - // method upon completion and as progress is made in the Write case. - virtual void DoTruncate(const GURL& path, int64 offset) = 0; - virtual void DoWrite(const GURL& path, - const GURL& blob_url, - int64 offset) = 0; - virtual void DoCancel() = 0; - - private: - enum OperationType { - kOperationNone, - kOperationWrite, - kOperationTruncate - }; - - enum CancelState { - kCancelNotInProgress, - kCancelSent, - kCancelReceivedWriteResponse, - }; - - void FinishCancel(); - - GURL path_; - WebKit::WebFileWriterClient* client_; - OperationType operation_; - CancelState cancel_state_; -}; - -} // namespace content - -#endif // CONTENT_CHILD_FILEAPI_WEBFILEWRITER_BASE_H_ diff --git a/chromium/content/child/fileapi/webfilewriter_base_unittest.cc b/chromium/content/child/fileapi/webfilewriter_base_unittest.cc deleted file mode 100644 index 92150813dfa..00000000000 --- a/chromium/content/child/fileapi/webfilewriter_base_unittest.cc +++ /dev/null @@ -1,411 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/child/fileapi/webfilewriter_base.h" - -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "base/message_loop/message_loop.h" -#include "base/strings/utf_string_conversions.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/WebKit/public/platform/WebURL.h" -#include "third_party/WebKit/public/web/WebFileError.h" -#include "third_party/WebKit/public/web/WebFileWriterClient.h" -#include "url/gurl.h" - -namespace content { - -namespace { - -// We use particular offsets to trigger particular behaviors -// in the TestableFileWriter. -const int kNoOffset = -1; -const int kBasicFileTruncate_Offset = 1; -const int kErrorFileTruncate_Offset = 2; -const int kCancelFileTruncate_Offset = 3; -const int kCancelFailedTruncate_Offset = 4; -const int kBasicFileWrite_Offset = 1; -const int kErrorFileWrite_Offset = 2; -const int kMultiFileWrite_Offset = 3; -const int kCancelFileWriteBeforeCompletion_Offset = 4; -const int kCancelFileWriteAfterCompletion_Offset = 5; - -GURL mock_path_as_gurl() { - return GURL("MockPath"); -} - -} // namespace - -class TestableFileWriter : public WebFileWriterBase { - public: - explicit TestableFileWriter(WebKit::WebFileWriterClient* client) - : WebFileWriterBase(mock_path_as_gurl(), client) { - reset(); - } - - void reset() { - received_truncate_ = false; - received_truncate_path_ = GURL(); - received_truncate_offset_ = kNoOffset; - received_write_ = false; - received_write_path_ = GURL(); - received_write_offset_ = kNoOffset; - received_write_blob_url_ = GURL(); - received_cancel_ = false; - } - - bool received_truncate_; - GURL received_truncate_path_; - int64 received_truncate_offset_; - bool received_write_; - GURL received_write_path_; - GURL received_write_blob_url_; - int64 received_write_offset_; - bool received_cancel_; - - protected: - virtual void DoTruncate(const GURL& path, int64 offset) OVERRIDE { - received_truncate_ = true; - received_truncate_path_ = path; - received_truncate_offset_ = offset; - - if (offset == kBasicFileTruncate_Offset) { - DidSucceed(); - } else if (offset == kErrorFileTruncate_Offset) { - DidFail(base::PLATFORM_FILE_ERROR_NOT_FOUND); - } else if (offset == kCancelFileTruncate_Offset) { - cancel(); - DidSucceed(); // truncate completion - DidSucceed(); // cancel completion - } else if (offset == kCancelFailedTruncate_Offset) { - cancel(); - DidFail(base::PLATFORM_FILE_ERROR_NOT_FOUND); // truncate completion - DidSucceed(); // cancel completion - } else { - FAIL(); - } - } - - virtual void DoWrite(const GURL& path, const GURL& blob_url, - int64 offset) OVERRIDE { - received_write_ = true; - received_write_path_ = path; - received_write_offset_ = offset; - received_write_blob_url_ = blob_url; - - if (offset == kBasicFileWrite_Offset) { - DidWrite(1, true); - } else if (offset == kErrorFileWrite_Offset) { - DidFail(base::PLATFORM_FILE_ERROR_NOT_FOUND); - } else if (offset == kMultiFileWrite_Offset) { - DidWrite(1, false); - DidWrite(1, false); - DidWrite(1, true); - } else if (offset == kCancelFileWriteBeforeCompletion_Offset) { - DidWrite(1, false); - cancel(); - DidWrite(1, false); - DidWrite(1, false); - DidFail(base::PLATFORM_FILE_ERROR_FAILED); // write completion - DidSucceed(); // cancel completion - } else if (offset == kCancelFileWriteAfterCompletion_Offset) { - DidWrite(1, false); - cancel(); - DidWrite(1, false); - DidWrite(1, false); - DidWrite(1, true); // write completion - DidFail(base::PLATFORM_FILE_ERROR_FAILED); // cancel completion - } else { - FAIL(); - } - } - - virtual void DoCancel() OVERRIDE { - received_cancel_ = true; - } -}; - -class FileWriterTest : public testing::Test, - public WebKit::WebFileWriterClient { - public: - FileWriterTest() { - reset(); - } - - WebKit::WebFileWriter* writer() { - return testable_writer_.get(); - } - - // WebFileWriterClient overrides - virtual void didWrite(long long bytes, bool complete) { - EXPECT_FALSE(received_did_write_complete_); - ++received_did_write_count_; - received_did_write_bytes_total_ += bytes; - if (complete) - received_did_write_complete_ = true; - - if (delete_in_client_callback_) - testable_writer_.reset(NULL); - } - - virtual void didTruncate() { - EXPECT_FALSE(received_did_truncate_); - received_did_truncate_ = true; - if (delete_in_client_callback_) - testable_writer_.reset(NULL); - } - - virtual void didFail(WebKit::WebFileError error) { - EXPECT_FALSE(received_did_fail_); - received_did_fail_ = true; - fail_error_received_ = error; - if (delete_in_client_callback_) - testable_writer_.reset(NULL); - } - - protected: - void reset() { - testable_writer_.reset(new TestableFileWriter(this)); - delete_in_client_callback_ = false; - received_did_write_count_ = 0; - received_did_write_bytes_total_ = 0; - received_did_write_complete_ = false; - received_did_truncate_ = false; - received_did_fail_ = false; - fail_error_received_ = static_cast<WebKit::WebFileError>(0); - } - - scoped_ptr<TestableFileWriter> testable_writer_; - bool delete_in_client_callback_; - - // Observed WebFileWriterClient artifacts. - int received_did_write_count_; - long long received_did_write_bytes_total_; - bool received_did_write_complete_; - bool received_did_truncate_; - bool received_did_fail_; - WebKit::WebFileError fail_error_received_; - - DISALLOW_COPY_AND_ASSIGN(FileWriterTest); -}; - -TEST_F(FileWriterTest, BasicFileWrite) { - // Call the webkit facing api. - const GURL kBlobUrl("blob://bloburl/"); - writer()->write(kBasicFileWrite_Offset, kBlobUrl); - - // Check that the derived class gets called correctly. - EXPECT_TRUE(testable_writer_->received_write_); - EXPECT_EQ(testable_writer_->received_write_path_, - mock_path_as_gurl()); - EXPECT_EQ(kBasicFileWrite_Offset, - testable_writer_->received_write_offset_); - EXPECT_EQ(kBlobUrl, testable_writer_->received_write_blob_url_); - EXPECT_FALSE(testable_writer_->received_truncate_); - EXPECT_FALSE(testable_writer_->received_cancel_); - - // Check that the client gets called correctly. - EXPECT_EQ(1, received_did_write_count_); - EXPECT_TRUE(received_did_write_complete_); - EXPECT_EQ(1, received_did_write_bytes_total_); - EXPECT_FALSE(received_did_truncate_); - EXPECT_FALSE(received_did_fail_); -} - -TEST_F(FileWriterTest, BasicFileTruncate) { - // Call the webkit facing api. - writer()->truncate(kBasicFileTruncate_Offset); - - // Check that the derived class gets called correctly. - EXPECT_TRUE(testable_writer_->received_truncate_); - EXPECT_EQ(mock_path_as_gurl(), - testable_writer_->received_truncate_path_); - EXPECT_EQ(kBasicFileTruncate_Offset, - testable_writer_->received_truncate_offset_); - EXPECT_FALSE(testable_writer_->received_write_); - EXPECT_FALSE(testable_writer_->received_cancel_); - - // Check that the client gets called correctly. - EXPECT_TRUE(received_did_truncate_); - EXPECT_EQ(0, received_did_write_count_); - EXPECT_FALSE(received_did_fail_); -} - -TEST_F(FileWriterTest, ErrorFileWrite) { - // Call the webkit facing api. - const GURL kBlobUrl("blob://bloburl/"); - writer()->write(kErrorFileWrite_Offset, kBlobUrl); - - // Check that the derived class gets called correctly. - EXPECT_TRUE(testable_writer_->received_write_); - EXPECT_EQ(testable_writer_->received_write_path_, - mock_path_as_gurl()); - EXPECT_EQ(kErrorFileWrite_Offset, - testable_writer_->received_write_offset_); - EXPECT_EQ(kBlobUrl, testable_writer_->received_write_blob_url_); - EXPECT_FALSE(testable_writer_->received_truncate_); - EXPECT_FALSE(testable_writer_->received_cancel_); - - // Check that the client gets called correctly. - EXPECT_TRUE(received_did_fail_); - EXPECT_EQ(WebKit::WebFileErrorNotFound, fail_error_received_); - EXPECT_EQ(0, received_did_write_count_); - EXPECT_FALSE(received_did_truncate_); -} - -TEST_F(FileWriterTest, ErrorFileTruncate) { - // Call the webkit facing api. - writer()->truncate(kErrorFileTruncate_Offset); - - // Check that the derived class gets called correctly. - EXPECT_TRUE(testable_writer_->received_truncate_); - EXPECT_EQ(mock_path_as_gurl(), - testable_writer_->received_truncate_path_); - EXPECT_EQ(kErrorFileTruncate_Offset, - testable_writer_->received_truncate_offset_); - EXPECT_FALSE(testable_writer_->received_write_); - EXPECT_FALSE(testable_writer_->received_cancel_); - - // Check that the client gets called correctly. - EXPECT_TRUE(received_did_fail_); - EXPECT_EQ(WebKit::WebFileErrorNotFound, fail_error_received_); - EXPECT_FALSE(received_did_truncate_); - EXPECT_EQ(0, received_did_write_count_); -} - -TEST_F(FileWriterTest, MultiFileWrite) { - // Call the webkit facing api. - const GURL kBlobUrl("blob://bloburl/"); - writer()->write(kMultiFileWrite_Offset, kBlobUrl); - - // Check that the derived class gets called correctly. - EXPECT_TRUE(testable_writer_->received_write_); - EXPECT_EQ(testable_writer_->received_write_path_, - mock_path_as_gurl()); - EXPECT_EQ(kMultiFileWrite_Offset, - testable_writer_->received_write_offset_); - EXPECT_EQ(kBlobUrl, testable_writer_->received_write_blob_url_); - EXPECT_FALSE(testable_writer_->received_truncate_); - EXPECT_FALSE(testable_writer_->received_cancel_); - - // Check that the client gets called correctly. - EXPECT_EQ(3, received_did_write_count_); - EXPECT_TRUE(received_did_write_complete_); - EXPECT_EQ(3, received_did_write_bytes_total_); - EXPECT_FALSE(received_did_truncate_); - EXPECT_FALSE(received_did_fail_); -} - -TEST_F(FileWriterTest, CancelFileWriteBeforeCompletion) { - // Call the webkit facing api. - const GURL kBlobUrl("blob://bloburl/"); - writer()->write(kCancelFileWriteBeforeCompletion_Offset, kBlobUrl); - - // Check that the derived class gets called correctly. - EXPECT_TRUE(testable_writer_->received_write_); - EXPECT_EQ(testable_writer_->received_write_path_, - mock_path_as_gurl()); - EXPECT_EQ(kCancelFileWriteBeforeCompletion_Offset, - testable_writer_->received_write_offset_); - EXPECT_EQ(kBlobUrl, testable_writer_->received_write_blob_url_); - EXPECT_TRUE(testable_writer_->received_cancel_); - EXPECT_FALSE(testable_writer_->received_truncate_); - - // Check that the client gets called correctly. - EXPECT_TRUE(received_did_fail_); - EXPECT_EQ(WebKit::WebFileErrorAbort, fail_error_received_); - EXPECT_EQ(1, received_did_write_count_); - EXPECT_FALSE(received_did_write_complete_); - EXPECT_EQ(1, received_did_write_bytes_total_); - EXPECT_FALSE(received_did_truncate_); -} - -TEST_F(FileWriterTest, CancelFileWriteAfterCompletion) { - // Call the webkit facing api. - const GURL kBlobUrl("blob://bloburl/"); - writer()->write(kCancelFileWriteAfterCompletion_Offset, kBlobUrl); - - // Check that the derived class gets called correctly. - EXPECT_TRUE(testable_writer_->received_write_); - EXPECT_EQ(testable_writer_->received_write_path_, - mock_path_as_gurl()); - EXPECT_EQ(kCancelFileWriteAfterCompletion_Offset, - testable_writer_->received_write_offset_); - EXPECT_EQ(kBlobUrl, testable_writer_->received_write_blob_url_); - EXPECT_TRUE(testable_writer_->received_cancel_); - EXPECT_FALSE(testable_writer_->received_truncate_); - - // Check that the client gets called correctly. - EXPECT_TRUE(received_did_fail_); - EXPECT_EQ(WebKit::WebFileErrorAbort, fail_error_received_); - EXPECT_EQ(1, received_did_write_count_); - EXPECT_FALSE(received_did_write_complete_); - EXPECT_EQ(1, received_did_write_bytes_total_); - EXPECT_FALSE(received_did_truncate_); -} - -TEST_F(FileWriterTest, CancelFileTruncate) { - // Call the webkit facing api. - writer()->truncate(kCancelFileTruncate_Offset); - - // Check that the derived class gets called correctly. - EXPECT_TRUE(testable_writer_->received_truncate_); - EXPECT_EQ(mock_path_as_gurl(), - testable_writer_->received_truncate_path_); - EXPECT_EQ(kCancelFileTruncate_Offset, - testable_writer_->received_truncate_offset_); - EXPECT_TRUE(testable_writer_->received_cancel_); - EXPECT_FALSE(testable_writer_->received_write_); - - // Check that the client gets called correctly. - EXPECT_TRUE(received_did_fail_); - EXPECT_EQ(WebKit::WebFileErrorAbort, fail_error_received_); - EXPECT_FALSE(received_did_truncate_); - EXPECT_EQ(0, received_did_write_count_); -} - -TEST_F(FileWriterTest, CancelFailedTruncate) { - // Call the webkit facing api. - writer()->truncate(kCancelFailedTruncate_Offset); - - // Check that the derived class gets called correctly. - EXPECT_TRUE(testable_writer_->received_truncate_); - EXPECT_EQ(mock_path_as_gurl(), - testable_writer_->received_truncate_path_); - EXPECT_EQ(kCancelFailedTruncate_Offset, - testable_writer_->received_truncate_offset_); - EXPECT_TRUE(testable_writer_->received_cancel_); - EXPECT_FALSE(testable_writer_->received_write_); - - // Check that the client gets called correctly. - EXPECT_TRUE(received_did_fail_); - EXPECT_EQ(WebKit::WebFileErrorAbort, fail_error_received_); - EXPECT_FALSE(received_did_truncate_); - EXPECT_EQ(0, received_did_write_count_); -} - -TEST_F(FileWriterTest, DeleteInCompletionCallbacks) { - delete_in_client_callback_ = true; - writer()->write(kBasicFileWrite_Offset, GURL("blob://bloburl/")); - EXPECT_FALSE(testable_writer_.get()); - - reset(); - delete_in_client_callback_ = true; - writer()->truncate(kBasicFileTruncate_Offset); - EXPECT_FALSE(testable_writer_.get()); - - reset(); - delete_in_client_callback_ = true; - writer()->write(kErrorFileWrite_Offset, GURL("blob://bloburl/")); - EXPECT_FALSE(testable_writer_.get()); - - reset(); - delete_in_client_callback_ = true; - writer()->truncate(kErrorFileTruncate_Offset); - EXPECT_FALSE(testable_writer_.get()); - - // Not crashing counts as passing. -} - -} // namespace content diff --git a/chromium/content/child/fileapi/webfilewriter_impl.h b/chromium/content/child/fileapi/webfilewriter_impl.h index 69b979b020d..e7b49b67b3c 100644 --- a/chromium/content/child/fileapi/webfilewriter_impl.h +++ b/chromium/content/child/fileapi/webfilewriter_impl.h @@ -8,12 +8,12 @@ #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "base/message_loop/message_loop_proxy.h" -#include "content/child/fileapi/webfilewriter_base.h" +#include "webkit/renderer/fileapi/webfilewriter_base.h" namespace content { // An implementation of WebFileWriter for use in chrome renderers and workers. -class WebFileWriterImpl : public WebFileWriterBase, +class WebFileWriterImpl : public fileapi::WebFileWriterBase, public base::SupportsWeakPtr<WebFileWriterImpl> { public: enum Type { diff --git a/chromium/content/child/runtime_features.cc b/chromium/content/child/runtime_features.cc index 25804aeee0a..120c12886af 100644 --- a/chromium/content/child/runtime_features.cc +++ b/chromium/content/child/runtime_features.cc @@ -29,7 +29,10 @@ static void SetRuntimeFeatureDefaultsForPlatform() { #endif // !defined(GOOGLE_TV) bool enable_webaudio = false; #if defined(ARCH_CPU_ARMEL) + // WebAudio needs Android MediaCodec API that was introduced in + // JellyBean, and also currently needs NEON support for the FFT. enable_webaudio = + (base::android::BuildInfo::GetInstance()->sdk_int() >= 16) && ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0); #endif // defined(ARCH_CPU_ARMEL) WebRuntimeFeatures::enableWebAudio(enable_webaudio); diff --git a/chromium/content/common/browser_plugin/browser_plugin_constants.cc b/chromium/content/common/browser_plugin/browser_plugin_constants.cc index 6da58e96c53..9ba17bcaeec 100644 --- a/chromium/content/common/browser_plugin/browser_plugin_constants.cc +++ b/chromium/content/common/browser_plugin/browser_plugin_constants.cc @@ -54,6 +54,10 @@ const char kLastUnlockedBySelf[] = "lastUnlockedBySelf"; const char kMessageText[] = "messageText"; const char kMessageType[] = "messageType"; const char kName[] = "name"; +const char kNewHeight[] = "newHeight"; +const char kNewWidth[] = "newWidth"; +const char kOldHeight[] = "oldHeight"; +const char kOldWidth[] = "oldWidth"; const char kPermission[] = "permission"; const char kPermissionTypeDialog[] = "dialog"; const char kPermissionTypeDownload[] = "download"; diff --git a/chromium/content/common/browser_plugin/browser_plugin_constants.h b/chromium/content/common/browser_plugin/browser_plugin_constants.h index 8e911f04ef2..7776a82c309 100644 --- a/chromium/content/common/browser_plugin/browser_plugin_constants.h +++ b/chromium/content/common/browser_plugin/browser_plugin_constants.h @@ -42,6 +42,9 @@ extern const char kAttributeName[]; extern const char kAttributePartition[]; extern const char kAttributeSrc[]; +// Events. +extern const char kEventSizeChanged[]; + // Parameters/properties on events. extern const char kDefaultPromptText[]; extern const char kId[]; @@ -51,6 +54,10 @@ extern const char kLastUnlockedBySelf[]; extern const char kMessageText[]; extern const char kMessageType[]; extern const char kName[]; +extern const char kNewHeight[]; +extern const char kNewWidth[]; +extern const char kOldHeight[]; +extern const char kOldWidth[]; extern const char kPermission[]; extern const char kPermissionTypeDialog[]; extern const char kPermissionTypeDownload[]; diff --git a/chromium/content/common/gpu/DEPS b/chromium/content/common/gpu/DEPS index 7d19c095cec..f42f973b19c 100644 --- a/chromium/content/common/gpu/DEPS +++ b/chromium/content/common/gpu/DEPS @@ -3,7 +3,6 @@ include_rules = [ "+libEGL", "+libGLESv2", "+media/video/video_decode_accelerator.h", - "+media/video/video_encode_accelerator.h", "+skia", "+third_party/mesa", diff --git a/chromium/content/common/gpu/client/gpu_channel_host.cc b/chromium/content/common/gpu/client/gpu_channel_host.cc index 2ee9f8e2b5d..601c06d9dac 100644 --- a/chromium/content/common/gpu/client/gpu_channel_host.cc +++ b/chromium/content/common/gpu/client/gpu_channel_host.cc @@ -13,7 +13,6 @@ #include "base/posix/eintr_wrapper.h" #include "base/threading/thread_restrictions.h" #include "content/common/gpu/client/command_buffer_proxy_impl.h" -#include "content/common/gpu/client/gpu_video_encode_accelerator_host.h" #include "content/common/gpu/gpu_messages.h" #include "gpu/command_buffer/common/mailbox.h" #include "ipc/ipc_sync_message_filter.h" @@ -185,21 +184,6 @@ scoped_ptr<media::VideoDecodeAccelerator> GpuChannelHost::CreateVideoDecoder( return proxy->CreateVideoDecoder(profile, client).Pass(); } -scoped_ptr<media::VideoEncodeAccelerator> GpuChannelHost::CreateVideoEncoder( - media::VideoEncodeAccelerator::Client* client) { - TRACE_EVENT0("gpu", "GpuChannelHost::CreateVideoEncoder"); - - scoped_ptr<media::VideoEncodeAccelerator> vea; - int32 route_id = MSG_ROUTING_NONE; - if (!Send(new GpuChannelMsg_CreateVideoEncoder(&route_id))) - return vea.Pass(); - if (route_id == MSG_ROUTING_NONE) - return vea.Pass(); - - vea.reset(new GpuVideoEncodeAcceleratorHost(client, this, route_id)); - return vea.Pass(); -} - void GpuChannelHost::DestroyCommandBuffer( CommandBufferProxyImpl* command_buffer) { TRACE_EVENT0("gpu", "GpuChannelHost::DestroyCommandBuffer"); diff --git a/chromium/content/common/gpu/client/gpu_channel_host.h b/chromium/content/common/gpu/client/gpu_channel_host.h index 9aa3673bc73..6decd17931b 100644 --- a/chromium/content/common/gpu/client/gpu_channel_host.h +++ b/chromium/content/common/gpu/client/gpu_channel_host.h @@ -23,7 +23,6 @@ #include "ipc/ipc_channel_proxy.h" #include "ipc/ipc_sync_channel.h" #include "media/video/video_decode_accelerator.h" -#include "media/video/video_encode_accelerator.h" #include "ui/gfx/native_widget_types.h" #include "ui/gfx/size.h" #include "ui/gl/gpu_preference.h" @@ -129,10 +128,6 @@ class GpuChannelHost : public IPC::Sender, media::VideoCodecProfile profile, media::VideoDecodeAccelerator::Client* client); - // Creates a video encoder in the GPU process. - scoped_ptr<media::VideoEncodeAccelerator> CreateVideoEncoder( - media::VideoEncodeAccelerator::Client* client); - // Destroy a command buffer created by this channel. void DestroyCommandBuffer(CommandBufferProxyImpl* command_buffer); diff --git a/chromium/content/common/gpu/client/gpu_video_decode_accelerator_host.cc b/chromium/content/common/gpu/client/gpu_video_decode_accelerator_host.cc index 66c39f9bab6..fcf36bf4eb3 100644 --- a/chromium/content/common/gpu/client/gpu_video_decode_accelerator_host.cc +++ b/chromium/content/common/gpu/client/gpu_video_decode_accelerator_host.cc @@ -37,11 +37,13 @@ GpuVideoDecodeAcceleratorHost::GpuVideoDecodeAcceleratorHost( void GpuVideoDecodeAcceleratorHost::OnChannelError() { DLOG(ERROR) << "GpuVideoDecodeAcceleratorHost::OnChannelError()"; - OnErrorNotification(PLATFORM_FAILURE); if (channel_) { channel_->RemoveRoute(decoder_route_id_); channel_ = NULL; } + // See OnErrorNotification for why this needs to be the last thing in this + // function. + OnErrorNotification(PLATFORM_FAILURE); } bool GpuVideoDecodeAcceleratorHost::OnMessageReceived(const IPC::Message& msg) { @@ -65,6 +67,8 @@ bool GpuVideoDecodeAcceleratorHost::OnMessageReceived(const IPC::Message& msg) { IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() DCHECK(handled); + // See OnErrorNotification for why |this| mustn't be used after + // OnErrorNotification might have been called above. return handled; } @@ -165,6 +169,8 @@ void GpuVideoDecodeAcceleratorHost::Send(IPC::Message* message) { DLOG(ERROR) << "Send(" << message_type << ") failed"; error = true; } + // See OnErrorNotification for why this needs to be the last thing in this + // function. if (error) OnErrorNotification(PLATFORM_FAILURE); } @@ -219,9 +225,13 @@ void GpuVideoDecodeAcceleratorHost::OnErrorNotification(uint32 error) { DCHECK(CalledOnValidThread()); if (!client_) return; - client_->NotifyError( + + // Client::NotifyError() may Destroy() |this|, so calling it needs to be the + // last thing done on this stack! + media::VideoDecodeAccelerator::Client* client = NULL; + std::swap(client, client_); + client->NotifyError( static_cast<media::VideoDecodeAccelerator::Error>(error)); - client_ = NULL; } } // namespace content diff --git a/chromium/content/common/gpu/client/gpu_video_encode_accelerator_host.cc b/chromium/content/common/gpu/client/gpu_video_encode_accelerator_host.cc deleted file mode 100644 index 64f07e5b081..00000000000 --- a/chromium/content/common/gpu/client/gpu_video_encode_accelerator_host.cc +++ /dev/null @@ -1,217 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/common/gpu/client/gpu_video_encode_accelerator_host.h" - -#include "base/logging.h" -#include "base/message_loop/message_loop_proxy.h" -#include "content/common/gpu/client/gpu_channel_host.h" -#include "content/common/gpu/gpu_messages.h" -#include "content/common/gpu/media/gpu_video_encode_accelerator.h" -#include "media/base/video_frame.h" - -namespace content { - -GpuVideoEncodeAcceleratorHost::GpuVideoEncodeAcceleratorHost( - media::VideoEncodeAccelerator::Client* client, - const scoped_refptr<GpuChannelHost>& gpu_channel_host, - int32 route_id) - : client_(client), - client_ptr_factory_(client_), - channel_(gpu_channel_host), - route_id_(route_id), - next_frame_id_(0) { - channel_->AddRoute(route_id_, AsWeakPtr()); -} - -GpuVideoEncodeAcceleratorHost::~GpuVideoEncodeAcceleratorHost() { - if (channel_) - channel_->RemoveRoute(route_id_); -} - -// static -std::vector<media::VideoEncodeAccelerator::SupportedProfile> -GpuVideoEncodeAcceleratorHost::GetSupportedProfiles() { - return GpuVideoEncodeAccelerator::GetSupportedProfiles(); -} - -bool GpuVideoEncodeAcceleratorHost::OnMessageReceived( - const IPC::Message& message) { - bool handled = true; - IPC_BEGIN_MESSAGE_MAP(GpuVideoEncodeAcceleratorHost, message) - IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderHostMsg_NotifyInitializeDone, - OnNotifyInitializeDone) - IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderHostMsg_RequireBitstreamBuffers, - OnRequireBitstreamBuffers) - IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderHostMsg_NotifyInputDone, - OnNotifyInputDone) - IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderHostMsg_BitstreamBufferReady, - OnBitstreamBufferReady) - IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderHostMsg_NotifyError, - OnNotifyError) - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - DCHECK(handled); - return handled; -} - -void GpuVideoEncodeAcceleratorHost::OnChannelError() { - DLOG(ERROR) << "OnChannelError()"; - OnNotifyError(kPlatformFailureError); - if (channel_) { - channel_->RemoveRoute(route_id_); - channel_ = NULL; - } -} - -void GpuVideoEncodeAcceleratorHost::Initialize( - media::VideoFrame::Format input_format, - const gfx::Size& input_visible_size, - media::VideoCodecProfile output_profile, - uint32 initial_bitrate) { - Send(new AcceleratedVideoEncoderMsg_Initialize(route_id_, - input_format, - input_visible_size, - output_profile, - initial_bitrate)); -} - -void GpuVideoEncodeAcceleratorHost::Encode( - const scoped_refptr<media::VideoFrame>& frame, - bool force_keyframe) { - if (!channel_) - return; - if (!base::SharedMemory::IsHandleValid(frame->shared_memory_handle())) { - DLOG(ERROR) << "Encode(): cannot encode frame not backed by shared memory"; - NotifyError(kPlatformFailureError); - return; - } - base::SharedMemoryHandle handle = - channel_->ShareToGpuProcess(frame->shared_memory_handle()); - if (!base::SharedMemory::IsHandleValid(handle)) { - DLOG(ERROR) << "Encode(): failed to duplicate buffer handle for GPU " - "process"; - NotifyError(kPlatformFailureError); - return; - } - - // We assume that planar frame data passed here is packed and contiguous. - const size_t plane_count = media::VideoFrame::NumPlanes(frame->format()); - size_t frame_size = 0; - for (size_t i = 0; i < plane_count; ++i) { - // Cast DCHECK parameters to void* to avoid printing uint8* as a string. - DCHECK_EQ(reinterpret_cast<void*>(frame->data(i)), - reinterpret_cast<void*>((frame->data(0) + frame_size))) - << "plane=" << i; - frame_size += frame->stride(i) * frame->rows(i); - } - - Send(new AcceleratedVideoEncoderMsg_Encode( - route_id_, next_frame_id_, handle, frame_size, force_keyframe)); - frame_map_[next_frame_id_] = frame; - - // Mask against 30 bits, to avoid (undefined) wraparound on signed integer. - next_frame_id_ = (next_frame_id_ + 1) & 0x3FFFFFFF; -} - -void GpuVideoEncodeAcceleratorHost::UseOutputBitstreamBuffer( - const media::BitstreamBuffer& buffer) { - if (!channel_) - return; - base::SharedMemoryHandle handle = - channel_->ShareToGpuProcess(buffer.handle()); - if (!base::SharedMemory::IsHandleValid(handle)) { - DLOG(ERROR) << "UseOutputBitstreamBuffer(): failed to duplicate buffer " - "handle for GPU process: buffer.id()=" << buffer.id(); - NotifyError(kPlatformFailureError); - return; - } - Send(new AcceleratedVideoEncoderMsg_UseOutputBitstreamBuffer( - route_id_, buffer.id(), handle, buffer.size())); -} - -void GpuVideoEncodeAcceleratorHost::RequestEncodingParametersChange( - uint32 bitrate, - uint32 framerate) { - Send(new AcceleratedVideoEncoderMsg_RequestEncodingParametersChange( - route_id_, bitrate, framerate)); -} - -void GpuVideoEncodeAcceleratorHost::Destroy() { - Send(new GpuChannelMsg_DestroyVideoEncoder(route_id_)); - delete this; -} - -void GpuVideoEncodeAcceleratorHost::NotifyError(Error error) { - DVLOG(2) << "NotifyError(): error=" << error; - base::MessageLoopProxy::current()->PostTask( - FROM_HERE, - base::Bind(&media::VideoEncodeAccelerator::Client::NotifyError, - client_ptr_factory_.GetWeakPtr(), - error)); -} - -void GpuVideoEncodeAcceleratorHost::OnNotifyInitializeDone() { - DVLOG(2) << "OnNotifyInitializeDone()"; - if (client_) - client_->NotifyInitializeDone(); -} - -void GpuVideoEncodeAcceleratorHost::OnRequireBitstreamBuffers( - uint32 input_count, - const gfx::Size& input_coded_size, - uint32 output_buffer_size) { - DVLOG(2) << "OnRequireBitstreamBuffers(): input_count=" << input_count - << ", input_coded_size=" << input_coded_size.ToString() - << ", output_buffer_size=" << output_buffer_size; - if (client_) { - client_->RequireBitstreamBuffers( - input_count, input_coded_size, output_buffer_size); - } -} - -void GpuVideoEncodeAcceleratorHost::OnNotifyInputDone(int32 frame_id) { - DVLOG(3) << "OnNotifyInputDone(): frame_id=" << frame_id; - if (!frame_map_.erase(frame_id)) { - DLOG(ERROR) << "OnNotifyInputDone(): " - "invalid frame_id=" << frame_id; - OnNotifyError(kPlatformFailureError); - return; - } -} - -void GpuVideoEncodeAcceleratorHost::OnBitstreamBufferReady( - int32 bitstream_buffer_id, - uint32 payload_size, - bool key_frame) { - DVLOG(3) << "OnBitstreamBufferReady(): " - "bitstream_buffer_id=" << bitstream_buffer_id - << ", payload_size=" << payload_size - << ", key_frame=" << key_frame; - if (client_) - client_->BitstreamBufferReady(bitstream_buffer_id, payload_size, key_frame); -} - -void GpuVideoEncodeAcceleratorHost::OnNotifyError(Error error) { - DVLOG(2) << "OnNotifyError(): error=" << error; - if (client_) { - client_->NotifyError(error); - client_ = NULL; - client_ptr_factory_.InvalidateWeakPtrs(); - } -} - -void GpuVideoEncodeAcceleratorHost::Send(IPC::Message* message) { - if (!channel_) { - DLOG(ERROR) << "Send(): no channel"; - delete message; - NotifyError(kPlatformFailureError); - } else if (!channel_->Send(message)) { - DLOG(ERROR) << "Send(): sending failed: message->type()=" - << message->type(); - NotifyError(kPlatformFailureError); - } -} - -} // namespace content diff --git a/chromium/content/common/gpu/client/gpu_video_encode_accelerator_host.h b/chromium/content/common/gpu/client/gpu_video_encode_accelerator_host.h deleted file mode 100644 index 860955d1142..00000000000 --- a/chromium/content/common/gpu/client/gpu_video_encode_accelerator_host.h +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_COMMON_GPU_CLIENT_GPU_VIDEO_ENCODE_ACCELERATOR_HOST_H_ -#define CONTENT_COMMON_GPU_CLIENT_GPU_VIDEO_ENCODE_ACCELERATOR_HOST_H_ - -#include <vector> - -#include "base/containers/hash_tables.h" -#include "base/memory/ref_counted.h" -#include "base/memory/weak_ptr.h" -#include "ipc/ipc_listener.h" -#include "media/video/video_encode_accelerator.h" - -namespace gfx { - -class Size; - -} // namespace gfx - -namespace media { - -class VideoFrame; - -} // namespace media - -namespace content { - -class GpuChannelHost; - -// This class is the renderer-side host for the VideoEncodeAccelerator in the -// GPU process, coordinated over IPC. -class GpuVideoEncodeAcceleratorHost - : public IPC::Listener, - public media::VideoEncodeAccelerator, - public base::SupportsWeakPtr<GpuVideoEncodeAcceleratorHost> { - public: - // |client| is assumed to outlive this object. Since the GpuChannelHost does - // _not_ own this object, a reference to |gpu_channel_host| is taken. - GpuVideoEncodeAcceleratorHost( - media::VideoEncodeAccelerator::Client* client, - const scoped_refptr<GpuChannelHost>& gpu_channel_host, - int32 route_id); - virtual ~GpuVideoEncodeAcceleratorHost(); - - // Static query for the supported profiles. This query proxies to - // GpuVideoEncodeAccelerator::GetSupportedProfiles(). - static std::vector<SupportedProfile> GetSupportedProfiles(); - - // IPC::Listener implementation. - virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; - virtual void OnChannelError() OVERRIDE; - - // media::VideoEncodeAccelerator implementation. - virtual void Initialize(media::VideoFrame::Format format, - const gfx::Size& input_visible_size, - media::VideoCodecProfile output_profile, - uint32 initial_bitrate) OVERRIDE; - virtual void Encode(const scoped_refptr<media::VideoFrame>& frame, - bool force_keyframe) OVERRIDE; - virtual void UseOutputBitstreamBuffer( - const media::BitstreamBuffer& buffer) OVERRIDE; - virtual void RequestEncodingParametersChange(uint32 bitrate, - uint32 framerate_num) OVERRIDE; - virtual void Destroy() OVERRIDE; - - private: - // Notify |client_| when an error has occured. Used when notifying from - // within a media::VideoEncodeAccelerator entry point, to avoid re-entrancy. - void NotifyError(Error error); - - // IPC handlers, proxying media::VideoEncodeAccelerator::Client for the GPU - // process. - void OnNotifyInitializeDone(); - void OnRequireBitstreamBuffers(uint32 input_count, - const gfx::Size& input_coded_size, - uint32 output_buffer_size); - void OnNotifyInputDone(int32 frame_id); - void OnBitstreamBufferReady(int32 bitstream_buffer_id, - uint32 payload_size, - bool key_frame); - void OnNotifyError(Error error); - - void Send(IPC::Message* message); - - // Weak pointer for client callbacks on the - // media::VideoEncodeAccelerator::Client interface. - media::VideoEncodeAccelerator::Client* client_; - // |client_ptr_factory_| is used for callbacks that need to be done through - // a PostTask() to avoid re-entrancy on the client. - base::WeakPtrFactory<VideoEncodeAccelerator::Client> client_ptr_factory_; - - // IPC channel and route ID. - scoped_refptr<GpuChannelHost> channel_; - const int32 route_id_; - - // media::VideoFrames sent to the encoder. - // base::IDMap not used here, since that takes pointers, not scoped_refptr. - typedef base::hash_map<int32, scoped_refptr<media::VideoFrame> > FrameMap; - FrameMap frame_map_; - - // ID serial number for the next frame to send to the GPU process. - int32 next_frame_id_; - - DISALLOW_COPY_AND_ASSIGN(GpuVideoEncodeAcceleratorHost); -}; - -} // namespace content - -#endif // CONTENT_COMMON_GPU_CLIENT_GPU_VIDEO_ENCODE_ACCELERATOR_HOST_H_ diff --git a/chromium/content/common/gpu/gpu_channel.cc b/chromium/content/common/gpu/gpu_channel.cc index 2b920d3a070..2e26fac38c8 100644 --- a/chromium/content/common/gpu/gpu_channel.cc +++ b/chromium/content/common/gpu/gpu_channel.cc @@ -20,7 +20,6 @@ #include "base/timer/timer.h" #include "content/common/gpu/gpu_channel_manager.h" #include "content/common/gpu/gpu_messages.h" -#include "content/common/gpu/media/gpu_video_encode_accelerator.h" #include "content/common/gpu/sync_point_manager.h" #include "content/public/common/content_switches.h" #include "crypto/hmac.h" @@ -755,12 +754,9 @@ bool GpuChannel::OnControlMessageReceived(const IPC::Message& msg) { bool handled = true; IPC_BEGIN_MESSAGE_MAP(GpuChannel, msg) IPC_MESSAGE_HANDLER(GpuChannelMsg_CreateOffscreenCommandBuffer, - OnCreateOffscreenCommandBuffer) + OnCreateOffscreenCommandBuffer) IPC_MESSAGE_HANDLER(GpuChannelMsg_DestroyCommandBuffer, - OnDestroyCommandBuffer) - IPC_MESSAGE_HANDLER(GpuChannelMsg_CreateVideoEncoder, OnCreateVideoEncoder) - IPC_MESSAGE_HANDLER(GpuChannelMsg_DestroyVideoEncoder, - OnDestroyVideoEncoder) + OnDestroyCommandBuffer) #if defined(OS_ANDROID) IPC_MESSAGE_HANDLER(GpuChannelMsg_RegisterStreamTextureProxy, OnRegisterStreamTextureProxy) @@ -903,26 +899,6 @@ void GpuChannel::OnDestroyCommandBuffer(int32 route_id) { } } -void GpuChannel::OnCreateVideoEncoder(int32* route_id) { - TRACE_EVENT0("gpu", "GpuChannel::OnCreateVideoEncoder"); - - *route_id = GenerateRouteID(); - GpuVideoEncodeAccelerator* encoder = - new GpuVideoEncodeAccelerator(this, *route_id); - router_.AddRoute(*route_id, encoder); - video_encoders_.AddWithID(encoder, *route_id); -} - -void GpuChannel::OnDestroyVideoEncoder(int32 route_id) { - TRACE_EVENT1( - "gpu", "GpuChannel::OnDestroyVideoEncoder", "route_id", route_id); - GpuVideoEncodeAccelerator* encoder = video_encoders_.Lookup(route_id); - if (!encoder) - return; - router_.RemoveRoute(route_id); - video_encoders_.Remove(route_id); -} - #if defined(OS_ANDROID) void GpuChannel::OnRegisterStreamTextureProxy( int32 stream_id, int32* route_id) { diff --git a/chromium/content/common/gpu/gpu_channel.h b/chromium/content/common/gpu/gpu_channel.h index 0692b903b4f..8d775f095fd 100644 --- a/chromium/content/common/gpu/gpu_channel.h +++ b/chromium/content/common/gpu/gpu_channel.h @@ -11,7 +11,6 @@ #include "base/id_map.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" -#include "base/memory/scoped_vector.h" #include "base/memory/weak_ptr.h" #include "base/process/process.h" #include "build/build_config.h" @@ -50,10 +49,9 @@ class StreamTextureManagerAndroid; namespace content { class GpuChannelManager; -class GpuChannelMessageFilter; struct GpuRenderingStats; -class GpuVideoEncodeAccelerator; class GpuWatchdog; +class GpuChannelMessageFilter; // Encapsulates an IPC channel between the GPU process and one renderer // process. On the renderer side there's a corresponding GpuChannelHost. @@ -175,8 +173,6 @@ class GpuChannel : public IPC::Listener, const GPUCreateCommandBufferConfig& init_params, int32* route_id); void OnDestroyCommandBuffer(int32 route_id); - void OnCreateVideoEncoder(int32* route_id); - void OnDestroyVideoEncoder(int32 route_id); #if defined(OS_ANDROID) // Register the StreamTextureProxy class with the gpu process so that all @@ -242,9 +238,6 @@ class GpuChannel : public IPC::Listener, StubMap stubs_; #endif // defined (ENABLE_GPU) - typedef IDMap<GpuVideoEncodeAccelerator, IDMapOwnPointer> EncoderMap; - EncoderMap video_encoders_; - bool log_messages_; // True if we should log sent and received messages. gpu::gles2::DisallowedFeatures disallowed_features_; GpuWatchdog* watchdog_; diff --git a/chromium/content/common/gpu/gpu_messages.h b/chromium/content/common/gpu/gpu_messages.h index 35c463517b1..fabc7a1a764 100644 --- a/chromium/content/common/gpu/gpu_messages.h +++ b/chromium/content/common/gpu/gpu_messages.h @@ -23,9 +23,7 @@ #include "gpu/ipc/gpu_command_buffer_traits.h" #include "ipc/ipc_channel_handle.h" #include "ipc/ipc_message_macros.h" -#include "media/base/video_frame.h" #include "media/video/video_decode_accelerator.h" -#include "media/video/video_encode_accelerator.h" #include "ui/base/latency_info.h" #include "ui/gfx/native_widget_types.h" #include "ui/gfx/size.h" @@ -221,10 +219,6 @@ IPC_STRUCT_TRAITS_BEGIN(content::GpuRenderingStats) IPC_STRUCT_TRAITS_MEMBER(total_processing_commands_time) IPC_STRUCT_TRAITS_END() -IPC_ENUM_TRAITS(media::VideoFrame::Format) - -IPC_ENUM_TRAITS(media::VideoEncodeAccelerator::Error) - //------------------------------------------------------------------------------ // GPU Messages // These are messages from the browser to the GPU process. @@ -455,12 +449,6 @@ IPC_MESSAGE_CONTROL1(GpuChannelMsg_GenerateMailboxNamesAsync, IPC_MESSAGE_CONTROL1(GpuChannelMsg_GenerateMailboxNamesReply, std::vector<gpu::Mailbox> /* mailbox_names */) -// Create a new GPU-accelerated video encoder. -IPC_SYNC_MESSAGE_CONTROL0_1(GpuChannelMsg_CreateVideoEncoder, - int32 /* route_id */) - -IPC_MESSAGE_CONTROL1(GpuChannelMsg_DestroyVideoEncoder, int32 /* route_id */) - #if defined(OS_ANDROID) // Register the StreamTextureProxy class with the GPU process, so that // the renderer process will get notified whenever a frame becomes available. @@ -704,64 +692,3 @@ IPC_MESSAGE_ROUTED0(AcceleratedVideoDecoderHostMsg_ResetDone) // Video decoder has encountered an error. IPC_MESSAGE_ROUTED1(AcceleratedVideoDecoderHostMsg_ErrorNotification, uint32) /* Error ID */ - -//------------------------------------------------------------------------------ -// Accelerated Video Encoder Messages -// These messages are sent from the Renderer process to GPU process. - -// Initialize the accelerated encoder. -IPC_MESSAGE_ROUTED4(AcceleratedVideoEncoderMsg_Initialize, - media::VideoFrame::Format /* input_format */, - gfx::Size /* input_visible_size */, - media::VideoCodecProfile /* output_profile */, - uint32 /* initial_bitrate */) - -// Queue a input buffer to the encoder to encode. |frame_id| will be returned by -// AcceleratedVideoEncoderHostMsg_NotifyEncodeDone. -IPC_MESSAGE_ROUTED4(AcceleratedVideoEncoderMsg_Encode, - int32 /* frame_id */, - base::SharedMemoryHandle /* buffer_handle */, - uint32 /* buffer_size */, - bool /* force_keyframe */) - -// Queue a buffer to the encoder for use in returning output. |buffer_id| will -// be returned by AcceleratedVideoEncoderHostMsg_BitstreamBufferReady. -IPC_MESSAGE_ROUTED3(AcceleratedVideoEncoderMsg_UseOutputBitstreamBuffer, - int32 /* buffer_id */, - base::SharedMemoryHandle /* buffer_handle */, - uint32 /* buffer_size */) - -// Request a runtime encoding parameter change. -IPC_MESSAGE_ROUTED2(AcceleratedVideoEncoderMsg_RequestEncodingParametersChange, - uint32 /* bitrate */, - uint32 /* framerate */) - -//------------------------------------------------------------------------------ -// Accelerated Video Encoder Host Messages -// These messages are sent from GPU process to Renderer process. - -// Notify of the completion of initialization. -IPC_MESSAGE_ROUTED0(AcceleratedVideoEncoderHostMsg_NotifyInitializeDone) - -// Notify renderer of the input/output buffer requirements of the encoder. -IPC_MESSAGE_ROUTED3(AcceleratedVideoEncoderHostMsg_RequireBitstreamBuffers, - uint32 /* input_count */, - gfx::Size /* input_coded_size */, - uint32 /* output_buffer_size */) - -// Notify the renderer that the encoder has finished using an input buffer. -// There is no congruent entry point in the media::VideoEncodeAccelerator -// interface, in VEA this same done condition is indicated by dropping the -// reference to the media::VideoFrame passed to VEA::Encode(). -IPC_MESSAGE_ROUTED1(AcceleratedVideoEncoderHostMsg_NotifyInputDone, - int32 /* frame_id */) - -// Notify the renderer that an output buffer has been filled with encoded data. -IPC_MESSAGE_ROUTED3(AcceleratedVideoEncoderHostMsg_BitstreamBufferReady, - int32 /* bitstream_buffer_id */, - uint32 /* payload_size */, - bool /* key_frame */) - -// Report error condition. -IPC_MESSAGE_ROUTED1(AcceleratedVideoEncoderHostMsg_NotifyError, - media::VideoEncodeAccelerator::Error /* error */) diff --git a/chromium/content/common/gpu/media/gpu_video_encode_accelerator.cc b/chromium/content/common/gpu/media/gpu_video_encode_accelerator.cc deleted file mode 100644 index b15f04bc619..00000000000 --- a/chromium/content/common/gpu/media/gpu_video_encode_accelerator.cc +++ /dev/null @@ -1,232 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/common/gpu/media/gpu_video_encode_accelerator.h" - -#include "base/callback.h" -#include "base/logging.h" -#include "base/memory/shared_memory.h" -#include "base/message_loop/message_loop_proxy.h" -#include "content/common/gpu/gpu_channel.h" -#include "content/common/gpu/gpu_messages.h" -#include "ipc/ipc_message_macros.h" -#include "media/base/video_frame.h" - -namespace content { - -GpuVideoEncodeAccelerator::GpuVideoEncodeAccelerator(GpuChannel* gpu_channel, - int32 route_id) - : weak_this_factory_(this), - channel_(gpu_channel), - route_id_(route_id), - input_format_(media::VideoFrame::INVALID), - output_buffer_size_(0) {} - -GpuVideoEncodeAccelerator::~GpuVideoEncodeAccelerator() { - if (encoder_) - encoder_.release()->Destroy(); -} - -bool GpuVideoEncodeAccelerator::OnMessageReceived(const IPC::Message& message) { - bool handled = true; - IPC_BEGIN_MESSAGE_MAP(GpuVideoEncodeAccelerator, message) - IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderMsg_Initialize, OnInitialize) - IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderMsg_Encode, OnEncode) - IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderMsg_UseOutputBitstreamBuffer, - OnUseOutputBitstreamBuffer) - IPC_MESSAGE_HANDLER( - AcceleratedVideoEncoderMsg_RequestEncodingParametersChange, - OnRequestEncodingParametersChange) - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - return handled; -} - -void GpuVideoEncodeAccelerator::OnChannelError() { - NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError); - if (channel_) - channel_ = NULL; -} - -void GpuVideoEncodeAccelerator::NotifyInitializeDone() { - Send(new AcceleratedVideoEncoderHostMsg_NotifyInitializeDone(route_id_)); -} - -void GpuVideoEncodeAccelerator::RequireBitstreamBuffers( - unsigned int input_count, - const gfx::Size& input_coded_size, - size_t output_buffer_size) { - Send(new AcceleratedVideoEncoderHostMsg_RequireBitstreamBuffers( - route_id_, input_count, input_coded_size, output_buffer_size)); - input_coded_size_ = input_coded_size; - output_buffer_size_ = output_buffer_size; -} - -void GpuVideoEncodeAccelerator::BitstreamBufferReady(int32 bitstream_buffer_id, - size_t payload_size, - bool key_frame) { - Send(new AcceleratedVideoEncoderHostMsg_BitstreamBufferReady( - route_id_, bitstream_buffer_id, payload_size, key_frame)); -} - -void GpuVideoEncodeAccelerator::NotifyError( - media::VideoEncodeAccelerator::Error error) { - Send(new AcceleratedVideoEncoderHostMsg_NotifyError(route_id_, error)); -} - -// static -std::vector<media::VideoEncodeAccelerator::SupportedProfile> -GpuVideoEncodeAccelerator::GetSupportedProfiles() { - std::vector<media::VideoEncodeAccelerator::SupportedProfile> profiles; - - // TODO(sheu): return platform-specific profiles. - return profiles; -} - -void GpuVideoEncodeAccelerator::CreateEncoder() { - // TODO(sheu): actual create the encoder. -} - -void GpuVideoEncodeAccelerator::OnInitialize( - media::VideoFrame::Format input_format, - const gfx::Size& input_visible_size, - media::VideoCodecProfile output_profile, - uint32 initial_bitrate) { - DVLOG(2) << "GpuVideoEncodeAccelerator::OnInitialize(): " - "input_format=" << input_format - << ", input_visible_size=" << input_visible_size.ToString() - << ", output_profile=" << output_profile - << ", initial_bitrate=" << initial_bitrate; - DCHECK(!encoder_); - - if (input_visible_size.width() > kint32max / input_visible_size.height()) { - DLOG(ERROR) << "GpuVideoEncodeAccelerator::OnInitialize(): " - "input_visible_size too large"; - NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError); - return; - } - - CreateEncoder(); - if (!encoder_) { - DLOG(ERROR) << "GpuVideoEncodeAccelerator::OnInitialize(): VEA creation " - "failed"; - NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError); - return; - } - encoder_->Initialize( - input_format, input_visible_size, output_profile, initial_bitrate); - input_format_ = input_format; - input_visible_size_ = input_visible_size; -} - -void GpuVideoEncodeAccelerator::OnEncode(int32 frame_id, - base::SharedMemoryHandle buffer_handle, - uint32 buffer_size, - bool force_keyframe) { - DVLOG(3) << "GpuVideoEncodeAccelerator::OnEncode(): frame_id=" << frame_id - << ", buffer_size=" << buffer_size - << ", force_keyframe=" << force_keyframe; - if (!encoder_) - return; - if (frame_id < 0) { - DLOG(ERROR) << "GpuVideoEncodeAccelerator::OnEncode(): invalid frame_id=" - << frame_id; - NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError); - return; - } - - scoped_ptr<base::SharedMemory> shm( - new base::SharedMemory(buffer_handle, true)); - if (!shm->Map(buffer_size)) { - DLOG(ERROR) << "GpuVideoEncodeAccelerator::OnEncode(): " - "could not map frame_id=" << frame_id; - NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError); - return; - } - - scoped_refptr<media::VideoFrame> frame = - media::VideoFrame::WrapExternalSharedMemory( - media::VideoFrame::I420, - input_coded_size_, - gfx::Rect(input_visible_size_), - input_visible_size_, - reinterpret_cast<uint8*>(shm->memory()), - buffer_handle, - base::TimeDelta(), - // It's turtles all the way down... - base::Bind(base::IgnoreResult(&base::MessageLoopProxy::PostTask), - base::MessageLoopProxy::current(), - FROM_HERE, - base::Bind(&GpuVideoEncodeAccelerator::EncodeFrameFinished, - weak_this_factory_.GetWeakPtr(), - frame_id, - base::Passed(&shm)))); - - if (!frame) { - DLOG(ERROR) << "GpuVideoEncodeAccelerator::OnEncode(): " - "could not create VideoFrame for frame_id=" << frame_id; - NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError); - return; - } - - encoder_->Encode(frame, force_keyframe); -} - -void GpuVideoEncodeAccelerator::OnUseOutputBitstreamBuffer( - int32 buffer_id, - base::SharedMemoryHandle buffer_handle, - uint32 buffer_size) { - DVLOG(3) << "GpuVideoEncodeAccelerator::OnUseOutputBitstreamBuffer(): " - "buffer_id=" << buffer_id - << ", buffer_size=" << buffer_size; - if (!encoder_) - return; - if (buffer_id < 0) { - DLOG(ERROR) << "GpuVideoEncodeAccelerator::OnUseOutputBitstreamBuffer(): " - "invalid buffer_id=" << buffer_id; - NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError); - return; - } - if (buffer_size < output_buffer_size_) { - DLOG(ERROR) << "GpuVideoEncodeAccelerator::OnUseOutputBitstreamBuffer(): " - "buffer too small for buffer_id=" << buffer_id; - NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError); - return; - } - encoder_->UseOutputBitstreamBuffer( - media::BitstreamBuffer(buffer_id, buffer_handle, buffer_size)); -} - -void GpuVideoEncodeAccelerator::OnRequestEncodingParametersChange( - uint32 bitrate, - uint32 framerate) { - DVLOG(2) << "GpuVideoEncodeAccelerator::OnRequestEncodingParametersChange(): " - "bitrate=" << bitrate - << ", framerate=" << framerate; - if (!encoder_) - return; - encoder_->RequestEncodingParametersChange(bitrate, framerate); -} - -void GpuVideoEncodeAccelerator::EncodeFrameFinished( - int32 frame_id, - scoped_ptr<base::SharedMemory> shm) { - Send(new AcceleratedVideoEncoderHostMsg_NotifyInputDone(route_id_, frame_id)); - // Just let shm fall out of scope. -} - -void GpuVideoEncodeAccelerator::Send(IPC::Message* message) { - if (!channel_) { - DLOG(ERROR) << "GpuVideoEncodeAccelerator::Send(): no channel"; - delete message; - return; - } else if (!channel_->Send(message)) { - DLOG(ERROR) << "GpuVideoEncodeAccelerator::Send(): sending failed: " - "message->type()=" << message->type(); - NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError); - return; - } -} - -} // namespace content diff --git a/chromium/content/common/gpu/media/gpu_video_encode_accelerator.h b/chromium/content/common/gpu/media/gpu_video_encode_accelerator.h deleted file mode 100644 index 5a48295e1e2..00000000000 --- a/chromium/content/common/gpu/media/gpu_video_encode_accelerator.h +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_COMMON_GPU_MEDIA_GPU_VIDEO_ENCODE_ACCELERATOR_H_ -#define CONTENT_COMMON_GPU_MEDIA_GPU_VIDEO_ENCODE_ACCELERATOR_H_ - -#include <vector> - -#include "base/memory/scoped_ptr.h" -#include "base/memory/weak_ptr.h" -#include "ipc/ipc_listener.h" -#include "media/video/video_encode_accelerator.h" -#include "ui/gfx/size.h" - -namespace base { - -class SharedMemory; - -} // namespace base - -namespace content { - -class GpuChannel; - -// This class encapsulates the GPU process view of a VideoEncodeAccelerator, -// wrapping the platform-specific VideoEncodeAccelerator instance. It handles -// IPC coming in from the renderer and passes it to the underlying VEA. -class GpuVideoEncodeAccelerator : public IPC::Listener, - public media::VideoEncodeAccelerator::Client { - public: - GpuVideoEncodeAccelerator(GpuChannel* gpu_channel, int32 route_id); - virtual ~GpuVideoEncodeAccelerator(); - - // IPC::Listener implementation - virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; - virtual void OnChannelError() OVERRIDE; - - // media::VideoEncodeAccelerator::Client implementation. - virtual void NotifyInitializeDone() OVERRIDE; - virtual void RequireBitstreamBuffers(unsigned int input_count, - const gfx::Size& input_coded_size, - size_t output_buffer_size) OVERRIDE; - virtual void BitstreamBufferReady(int32 bitstream_buffer_id, - size_t payload_size, - bool key_frame) OVERRIDE; - virtual void NotifyError(media::VideoEncodeAccelerator::Error error) OVERRIDE; - - // Static query for supported profiles. This query calls the appropriate - // platform-specific version. - static std::vector<media::VideoEncodeAccelerator::SupportedProfile> - GetSupportedProfiles(); - - private: - // Create the appropriate platform-specific VEA. - void CreateEncoder(); - - // IPC handlers, proxying media::VideoEncodeAccelerator for the renderer - // process. - void OnInitialize(media::VideoFrame::Format input_format, - const gfx::Size& input_visible_size, - media::VideoCodecProfile output_profile, - uint32 initial_bitrate); - void OnEncode(int32 frame_id, - base::SharedMemoryHandle buffer_handle, - uint32 buffer_size, - bool force_keyframe); - void OnUseOutputBitstreamBuffer(int32 buffer_id, - base::SharedMemoryHandle buffer_handle, - uint32 buffer_size); - void OnRequestEncodingParametersChange(uint32 bitrate, uint32 framerate); - - void EncodeFrameFinished(int32 frame_id, scoped_ptr<base::SharedMemory> shm); - - void Send(IPC::Message* message); - - // Weak pointer for media::VideoFrames that refer back to |this|. - base::WeakPtrFactory<GpuVideoEncodeAccelerator> weak_this_factory_; - - // The GpuChannel owns this GpuVideoEncodeAccelerator and will outlive |this|. - GpuChannel* channel_; - const int32 route_id_; - - // Owned pointer to the underlying VideoEncodeAccelerator. - scoped_ptr<media::VideoEncodeAccelerator> encoder_; - - // Video encoding parameters. - media::VideoFrame::Format input_format_; - gfx::Size input_visible_size_; - gfx::Size input_coded_size_; - size_t output_buffer_size_; - - DISALLOW_COPY_AND_ASSIGN(GpuVideoEncodeAccelerator); -}; - -} // namespace content - -#endif // CONTENT_COMMON_GPU_MEDIA_GPU_VIDEO_ENCODE_ACCELERATOR_H_ diff --git a/chromium/content/common/gpu/media/vaapi_h264_decoder.cc b/chromium/content/common/gpu/media/vaapi_h264_decoder.cc index 77739ce434f..78570b17440 100644 --- a/chromium/content/common/gpu/media/vaapi_h264_decoder.cc +++ b/chromium/content/common/gpu/media/vaapi_h264_decoder.cc @@ -1441,10 +1441,6 @@ bool VaapiH264Decoder::ProcessSPS(int sps_id, bool* need_new_buffers) { size_t max_dpb_size = std::min(max_dpb_mbs / (width_mb * height_mb), static_cast<int>(H264DPB::kDPBMaxSize)); DVLOG(1) << "Codec level: " << level << ", DPB size: " << max_dpb_size; - if (max_dpb_size == 0) { - DVLOG(1) << "Invalid DPB Size"; - return false; - } dpb_.set_max_num_pics(max_dpb_size); diff --git a/chromium/content/common/handle_enumerator_win.cc b/chromium/content/common/handle_enumerator_win.cc index 4e17aa2ca7d..98e232e1d20 100644 --- a/chromium/content/common/handle_enumerator_win.cc +++ b/chromium/content/common/handle_enumerator_win.cc @@ -174,6 +174,8 @@ string16 GetAccessString(HandleType handle_type, output.append(ASCIIToUTF16("\tFILE_WRITE_DATA\n")); if (access & FILE_WRITE_EA) output.append(ASCIIToUTF16("\tFILE_WRITE_EA\n")); + if (access & FILE_WRITE_EA) + output.append(ASCIIToUTF16("\tFILE_WRITE_EA\n")); break; case DirectoryHandle: if (access & FILE_ADD_FILE) diff --git a/chromium/content/common/media/media_stream_options.cc b/chromium/content/common/media/media_stream_options.cc index e042d8c2d28..4a3ace519d3 100644 --- a/chromium/content/common/media/media_stream_options.cc +++ b/chromium/content/common/media/media_stream_options.cc @@ -13,7 +13,6 @@ const char kMediaStreamSourceId[] = "chromeMediaSourceId"; const char kMediaStreamSourceInfoId[] = "sourceId"; const char kMediaStreamSourceTab[] = "tab"; const char kMediaStreamSourceScreen[] = "screen"; -const char kMediaStreamSourceDesktop[] = "desktop"; const char kMediaStreamSourceSystem[] = "system"; StreamOptions::StreamOptions() diff --git a/chromium/content/common/media/media_stream_options.h b/chromium/content/common/media/media_stream_options.h index bbb1aa4b8cd..e3faf268e3c 100644 --- a/chromium/content/common/media/media_stream_options.h +++ b/chromium/content/common/media/media_stream_options.h @@ -19,7 +19,6 @@ CONTENT_EXPORT extern const char kMediaStreamSourceId[]; CONTENT_EXPORT extern const char kMediaStreamSourceInfoId[]; CONTENT_EXPORT extern const char kMediaStreamSourceTab[]; CONTENT_EXPORT extern const char kMediaStreamSourceScreen[]; -CONTENT_EXPORT extern const char kMediaStreamSourceDesktop[]; CONTENT_EXPORT extern const char kMediaStreamSourceSystem[]; // StreamOptions is a Chromium representation of WebKit's diff --git a/chromium/content/common/mime_registry_messages.h b/chromium/content/common/mime_registry_messages.h index 32467214b30..e698369709e 100644 --- a/chromium/content/common/mime_registry_messages.h +++ b/chromium/content/common/mime_registry_messages.h @@ -20,4 +20,7 @@ IPC_SYNC_MESSAGE_CONTROL1_1(MimeRegistryMsg_GetMimeTypeFromExtension, IPC_SYNC_MESSAGE_CONTROL1_1(MimeRegistryMsg_GetMimeTypeFromFile, base::FilePath /* file_path */, std::string /* mime_type */) +IPC_SYNC_MESSAGE_CONTROL1_1(MimeRegistryMsg_GetPreferredExtensionForMimeType, + std::string /* mime_type */, + base::FilePath::StringType /* extension */) diff --git a/chromium/content/common/plugin_list.cc b/chromium/content/common/plugin_list.cc index 69102c5c68f..d623fad337d 100644 --- a/chromium/content/common/plugin_list.cc +++ b/chromium/content/common/plugin_list.cc @@ -59,11 +59,7 @@ void PluginList::AddExtraPluginPath(const base::FilePath& plugin_path) { void PluginList::RemoveExtraPluginPath(const base::FilePath& plugin_path) { base::AutoLock lock(lock_); - std::vector<base::FilePath>::iterator it = - std::find(extra_plugin_paths_.begin(), extra_plugin_paths_.end(), - plugin_path); - if (it != extra_plugin_paths_.end()) - extra_plugin_paths_.erase(it); + RemoveExtraPluginPathLocked(plugin_path); } void PluginList::AddExtraPluginDir(const base::FilePath& plugin_dir) { @@ -90,13 +86,16 @@ void PluginList::RegisterInternalPlugin(const WebPluginInfo& info, void PluginList::UnregisterInternalPlugin(const base::FilePath& path) { base::AutoLock lock(lock_); + bool found = false; for (size_t i = 0; i < internal_plugins_.size(); i++) { if (internal_plugins_[i].path == path) { internal_plugins_.erase(internal_plugins_.begin() + i); - return; + found = true; + break; } } - NOTREACHED(); + DCHECK(found); + RemoveExtraPluginPathLocked(path); } void PluginList::GetInternalPlugins( @@ -399,6 +398,16 @@ bool PluginList::SupportsExtension(const WebPluginInfo& plugin, return false; } +void PluginList::RemoveExtraPluginPathLocked( + const base::FilePath& plugin_path) { + lock_.AssertAcquired(); + std::vector<base::FilePath>::iterator it = + std::find(extra_plugin_paths_.begin(), extra_plugin_paths_.end(), + plugin_path); + if (it != extra_plugin_paths_.end()) + extra_plugin_paths_.erase(it); +} + PluginList::~PluginList() { } diff --git a/chromium/content/common/plugin_list.h b/chromium/content/common/plugin_list.h index 9a5ef863388..1205238706b 100644 --- a/chromium/content/common/plugin_list.h +++ b/chromium/content/common/plugin_list.h @@ -197,6 +197,11 @@ class CONTENT_EXPORT PluginList { bool SupportsExtension(const WebPluginInfo& plugin, const std::string& extension, std::string* actual_mime_type); + + // Removes |plugin_path| from the list of extra plugin paths. Should only be + // called while holding |lock_|. + void RemoveExtraPluginPathLocked(const base::FilePath& plugin_path); + // // Command-line switches // diff --git a/chromium/content/common/sandbox_init_win.cc b/chromium/content/common/sandbox_init_win.cc index dffb3344862..3afa12242a2 100644 --- a/chromium/content/common/sandbox_init_win.cc +++ b/chromium/content/common/sandbox_init_win.cc @@ -15,6 +15,8 @@ namespace content { bool InitializeSandbox(sandbox::SandboxInterfaceInfo* sandbox_info) { const CommandLine& command_line = *CommandLine::ForCurrentProcess(); + std::string process_type = + command_line.GetSwitchValueASCII(switches::kProcessType); sandbox::BrokerServices* broker_services = sandbox_info->broker_services; if (broker_services) { if (!InitBrokerServices(broker_services)) diff --git a/chromium/content/common/view_messages.h b/chromium/content/common/view_messages.h index 9ab0e9928c9..537aef3d026 100644 --- a/chromium/content/common/view_messages.h +++ b/chromium/content/common/view_messages.h @@ -339,6 +339,9 @@ IPC_STRUCT_BEGIN(ViewHostMsg_CreateWindow_Params) // The URL of the frame initiating the open. IPC_STRUCT_MEMBER(GURL, opener_url) + // The URL of the top frame containing the opener. + IPC_STRUCT_MEMBER(GURL, opener_top_level_frame_url) + // The security origin of the frame initiating the open. IPC_STRUCT_MEMBER(GURL, opener_security_origin) diff --git a/chromium/content/content_browser.gypi b/chromium/content/content_browser.gypi index 8a37d91ba24..441b2d0d027 100644 --- a/chromium/content/content_browser.gypi +++ b/chromium/content/content_browser.gypi @@ -528,6 +528,10 @@ 'browser/gamepad/gamepad_standard_mappings_win.cc', 'browser/gamepad/xbox_data_fetcher_mac.cc', 'browser/gamepad/xbox_data_fetcher_mac.h', + 'browser/geolocation/core_location_data_provider_mac.h', + 'browser/geolocation/core_location_data_provider_mac.mm', + 'browser/geolocation/core_location_provider_mac.h', + 'browser/geolocation/core_location_provider_mac.mm', 'browser/geolocation/device_data_provider.cc', 'browser/geolocation/device_data_provider.h', 'browser/geolocation/empty_device_data_provider.cc', diff --git a/chromium/content/content_child.gypi b/chromium/content/content_child.gypi index 05232b6e352..dd980e3b526 100644 --- a/chromium/content/content_child.gypi +++ b/chromium/content/content_child.gypi @@ -47,8 +47,6 @@ 'child/fileapi/webfilesystem_callback_adapters.h', 'child/fileapi/webfilesystem_impl.cc', 'child/fileapi/webfilesystem_impl.h', - 'child/fileapi/webfilewriter_base.cc', - 'child/fileapi/webfilewriter_base.h', 'child/fileapi/webfilewriter_impl.cc', 'child/fileapi/webfilewriter_impl.h', 'child/image_decoder.cc', diff --git a/chromium/content/content_common.gypi b/chromium/content/content_common.gypi index 0747f022076..057754837e3 100644 --- a/chromium/content/content_common.gypi +++ b/chromium/content/content_common.gypi @@ -197,8 +197,6 @@ 'common/gpu/client/gpu_channel_host.h', 'common/gpu/client/gpu_video_decode_accelerator_host.cc', 'common/gpu/client/gpu_video_decode_accelerator_host.h', - 'common/gpu/client/gpu_video_encode_accelerator_host.cc', - 'common/gpu/client/gpu_video_encode_accelerator_host.h', 'common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc', 'common/gpu/client/webgraphicscontext3d_command_buffer_impl.h', 'common/gpu/gpu_channel.cc', @@ -237,8 +235,6 @@ 'common/gpu/media/h264_parser.h', 'common/gpu/media/gpu_video_decode_accelerator.cc', 'common/gpu/media/gpu_video_decode_accelerator.h', - 'common/gpu/media/gpu_video_encode_accelerator.cc', - 'common/gpu/media/gpu_video_encode_accelerator.h', 'common/gpu/sync_point_manager.h', 'common/gpu/sync_point_manager.cc', 'common/gpu/texture_image_transport_surface.h', diff --git a/chromium/content/content_renderer.gypi b/chromium/content/content_renderer.gypi index 5c6358870b0..fc539f104dc 100644 --- a/chromium/content/content_renderer.gypi +++ b/chromium/content/content_renderer.gypi @@ -23,6 +23,7 @@ '../webkit/renderer/compositor_bindings/compositor_bindings.gyp:webkit_compositor_support', '../webkit/renderer/webkit_renderer.gyp:webkit_renderer', '../webkit/storage_common.gyp:webkit_storage_common', + '../webkit/storage_renderer.gyp:webkit_storage_renderer', '../webkit/support/webkit_support.gyp:glue', '../webkit/support/webkit_support.gyp:glue_child', ], @@ -214,8 +215,8 @@ 'renderer/media/preload.h', 'renderer/media/render_media_log.cc', 'renderer/media/render_media_log.h', - 'renderer/media/renderer_gpu_video_accelerator_factories.cc', - 'renderer/media/renderer_gpu_video_accelerator_factories.h', + 'renderer/media/renderer_gpu_video_decoder_factories.cc', + 'renderer/media/renderer_gpu_video_decoder_factories.h', 'renderer/media/renderer_webaudiodevice_impl.cc', 'renderer/media/renderer_webaudiodevice_impl.h', 'renderer/media/renderer_webmidiaccessor_impl.cc', @@ -474,6 +475,8 @@ 'renderer/renderer_webcolorchooser_impl.h', 'renderer/renderer_webkitplatformsupport_impl.cc', 'renderer/renderer_webkitplatformsupport_impl.h', + 'renderer/rendering_benchmark.cc', + 'renderer/rendering_benchmark.h', 'renderer/sad_plugin.cc', 'renderer/sad_plugin.h', 'renderer/savable_resources.cc', @@ -609,10 +612,6 @@ 'renderer/media/rtc_video_decoder.h', 'renderer/media/rtc_video_decoder_factory.cc', 'renderer/media/rtc_video_decoder_factory.h', - 'renderer/media/rtc_video_encoder.cc', - 'renderer/media/rtc_video_encoder.h', - 'renderer/media/rtc_video_encoder_factory.cc', - 'renderer/media/rtc_video_encoder_factory.h', 'renderer/media/video_destination_handler.cc', 'renderer/media/video_destination_handler.h', 'renderer/media/video_source_handler.cc', diff --git a/chromium/content/content_shell.gypi b/chromium/content/content_shell.gypi index 10cb53a2276..ae9012e96fd 100644 --- a/chromium/content/content_shell.gypi +++ b/chromium/content/content_shell.gypi @@ -723,8 +723,6 @@ '../base/base.gyp:base_java', '../media/media.gyp:media_java', '../net/net.gyp:net_java', - '../tools/android/forwarder/forwarder.gyp:forwarder', - '../tools/android/md5sum/md5sum.gyp:md5sum', '../ui/ui.gyp:ui_java', ], 'variables': { diff --git a/chromium/content/content_tests.gypi b/chromium/content/content_tests.gypi index c66cb598476..59158ca7c97 100644 --- a/chromium/content/content_tests.gypi +++ b/chromium/content/content_tests.gypi @@ -182,6 +182,7 @@ '../webkit/support/webkit_support.gyp:webkit_support_common', '../webkit/storage_browser.gyp:webkit_storage_browser', '../webkit/storage_common.gyp:webkit_storage_common', + '../webkit/storage_renderer.gyp:webkit_storage_renderer', ], }], ['OS == "win" or toolkit_uses_gtk == 1', { @@ -389,7 +390,6 @@ 'browser/web_contents/web_drag_source_mac_unittest.mm', 'browser/webui/web_ui_data_source_unittest.cc', 'browser/webui/web_ui_message_handler_unittest.cc', - 'child/fileapi/webfilewriter_base_unittest.cc', 'child/indexed_db/indexed_db_dispatcher_unittest.cc', 'child/indexed_db/proxy_webidbcursor_impl_unittest.cc', 'child/npapi/plugin_lib_unittest.cc', @@ -511,11 +511,11 @@ '../webkit/browser/fileapi/mock_file_system_options.h', '../webkit/browser/fileapi/native_file_util_unittest.cc', '../webkit/browser/fileapi/obfuscated_file_util_unittest.cc', + '../webkit/browser/fileapi/sandbox_context_unittest.cc', '../webkit/browser/fileapi/sandbox_database_test_helper.cc', '../webkit/browser/fileapi/sandbox_database_test_helper.h', '../webkit/browser/fileapi/sandbox_directory_database_unittest.cc', '../webkit/browser/fileapi/sandbox_file_system_backend_unittest.cc', - '../webkit/browser/fileapi/sandbox_file_system_backend_delegate_unittest.cc', '../webkit/browser/fileapi/sandbox_file_system_test_helper.cc', '../webkit/browser/fileapi/sandbox_file_system_test_helper.h', '../webkit/browser/fileapi/sandbox_isolated_origin_database_unittest.cc', @@ -549,6 +549,7 @@ '../webkit/browser/quota/quota_temporary_storage_evictor_unittest.cc', '../webkit/browser/quota/usage_tracker_unittest.cc', '../webkit/renderer/cpp_variant_unittest.cc', + '../webkit/renderer/fileapi/webfilewriter_base_unittest.cc', ], 'conditions': [ ['OS == "ios"', { @@ -586,6 +587,7 @@ '../webkit/renderer/webkit_renderer.gyp:webkit_renderer', '../webkit/storage_browser.gyp:webkit_storage_browser', '../webkit/storage_common.gyp:webkit_storage_common', + '../webkit/storage_renderer.gyp:webkit_storage_renderer', '../webkit/support/webkit_support.gyp:glue', '../webkit/support/webkit_support.gyp:glue_child', ], @@ -1236,6 +1238,7 @@ '../media/media.gyp:media_test_support', '../net/net.gyp:net_java', '../net/net.gyp:net_javatests', + '../tools/android/forwarder2/forwarder.gyp:forwarder2', ], 'variables': { 'apk_name': 'ContentShellTest', diff --git a/chromium/content/public/android/java/res/values-v17/styles.xml b/chromium/content/public/android/java/res/values-v17/styles.xml new file mode 100644 index 00000000000..aaeb6d759d6 --- /dev/null +++ b/chromium/content/public/android/java/res/values-v17/styles.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> + +<resources> + <style name="ContentActionBar"> + <item name="action_mode_share_drawable">@drawable/ic_menu_share_holo_light</item> + <item name="action_mode_web_search_drawable">@drawable/ic_menu_search_holo_light</item> + </style> + <style name="SelectPopupDialog"> + <item name="select_dialog_singlechoice">@android:layout/select_dialog_singlechoice</item> + <item name="select_dialog_multichoice">@android:layout/select_dialog_multichoice</item> + </style> +</resources> diff --git a/chromium/content/public/android/java/res/values/attrs.xml b/chromium/content/public/android/java/res/values/attrs.xml new file mode 100644 index 00000000000..8014143954b --- /dev/null +++ b/chromium/content/public/android/java/res/values/attrs.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> + +<resources> + <attr name="action_mode_share_drawable" format="reference" /> + <attr name="action_mode_web_search_drawable" format="reference" /> + <attr name="select_dialog_multichoice" format="reference" /> + <attr name="select_dialog_singlechoice" format="reference" /> +</resources> diff --git a/chromium/content/public/android/java/resource_map/org/chromium/content/R.java b/chromium/content/public/android/java/resource_map/org/chromium/content/R.java index ea936839690..6204c72a058 100644 --- a/chromium/content/public/android/java/resource_map/org/chromium/content/R.java +++ b/chromium/content/public/android/java/resource_map/org/chromium/content/R.java @@ -16,12 +16,16 @@ package org.chromium.content; * com.android.internal.R. */ public final class R { + public static final class attr { + public static int action_mode_share_drawable; + public static int action_mode_web_search_drawable; + public static int select_dialog_multichoice; + public static int select_dialog_singlechoice; + } public static final class dimen { public static int link_preview_overlay_radius; } public static final class drawable { - public static int ic_menu_search_holo_light; - public static int ic_menu_share_holo_light; public static int ondemand_overlay; } public static final class id { @@ -56,4 +60,8 @@ public final class R { public static int month_picker_dialog_title; public static int week_picker_dialog_title; } + public static final class style { + public static int ContentActionBar; + public static int SelectPopupDialog; + } } diff --git a/chromium/content/public/android/java/src/org/chromium/content/browser/ContentView.java b/chromium/content/public/android/java/src/org/chromium/content/browser/ContentView.java index c1d7b0aab00..f4c358bb0ad 100644 --- a/chromium/content/public/android/java/src/org/chromium/content/browser/ContentView.java +++ b/chromium/content/public/android/java/src/org/chromium/content/browser/ContentView.java @@ -101,6 +101,9 @@ public class ContentView extends FrameLayout setVerticalScrollBarEnabled(false); } + setFocusable(true); + setFocusableInTouchMode(true); + mContentViewCore = new ContentViewCore(context); mContentViewCore.initialize(this, this, nativeWebContents, windowAndroid, Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN ? @@ -441,6 +444,12 @@ public class ContentView extends FrameLayout } @Override + public void onWindowFocusChanged(boolean hasWindowFocus) { + super.onWindowFocusChanged(hasWindowFocus); + mContentViewCore.onWindowFocusChanged(hasWindowFocus); + } + + @Override public boolean onKeyUp(int keyCode, KeyEvent event) { return mContentViewCore.onKeyUp(keyCode, event); } diff --git a/chromium/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java b/chromium/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java index 6b65a9c5774..531417fb419 100644 --- a/chromium/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java +++ b/chromium/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java @@ -27,6 +27,7 @@ import android.text.Editable; import android.util.Log; import android.util.Pair; import android.view.ActionMode; +import android.view.HapticFeedbackConstants; import android.view.InputDevice; import android.view.KeyEvent; import android.view.MotionEvent; @@ -58,8 +59,8 @@ import org.chromium.content.browser.accessibility.BrowserAccessibilityManager; import org.chromium.content.browser.input.AdapterInputConnection; import org.chromium.content.browser.input.HandleView; import org.chromium.content.browser.input.ImeAdapter; -import org.chromium.content.browser.input.InputMethodManagerWrapper; import org.chromium.content.browser.input.ImeAdapter.AdapterInputConnectionFactory; +import org.chromium.content.browser.input.InputMethodManagerWrapper; import org.chromium.content.browser.input.InsertionHandleController; import org.chromium.content.browser.input.SelectPopupDialog; import org.chromium.content.browser.input.SelectionHandleController; @@ -71,7 +72,6 @@ import org.chromium.ui.gfx.DeviceDisplayInfo; import java.lang.annotation.Annotation; import java.lang.reflect.Field; -import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -403,6 +403,12 @@ import java.util.Map; // The AccessibilityInjector that handles loading Accessibility scripts into the web page. private AccessibilityInjector mAccessibilityInjector; + // Whether native accessibility, i.e. without any script injection, is allowed. + private boolean mNativeAccessibilityAllowed; + + // Whether native accessibility, i.e. without any script injection, has been enabled. + private boolean mNativeAccessibilityEnabled; + // Handles native accessibility, i.e. without any script injection. private BrowserAccessibilityManager mBrowserAccessibilityManager; @@ -519,9 +525,9 @@ import java.util.Map; // The anchor view should not go outside the bounds of the ContainerView. int leftMargin = Math.round(x * scale); int topMargin = Math.round(mRenderCoordinates.getContentOffsetYPix() + y * scale); + int scaledWidth = Math.round(width * scale); // ContentViewCore currently only supports these two container view types. if (mContainerView instanceof FrameLayout) { - int scaledWidth = Math.round(width * scale); if (scaledWidth + leftMargin > mContainerView.getWidth()) { scaledWidth = mContainerView.getWidth() - leftMargin; } @@ -538,9 +544,10 @@ import java.util.Map; // these models. leftMargin += mRenderCoordinates.getScrollXPixInt(); topMargin += mRenderCoordinates.getScrollYPixInt(); + android.widget.AbsoluteLayout.LayoutParams lp = - new android.widget.AbsoluteLayout.LayoutParams((int)width, - (int)(height * scale), leftMargin, topMargin); + new android.widget.AbsoluteLayout.LayoutParams( + scaledWidth, (int)(height * scale), leftMargin, topMargin); view.setLayoutParams(lp); } else { Log.e(TAG, "Unknown layout " + mContainerView.getClass().getName()); @@ -757,8 +764,6 @@ import java.util.Map; mContainerViewInternals = internalDispatcher; mContainerView.setWillNotDraw(false); - mContainerView.setFocusable(true); - mContainerView.setFocusableInTouchMode(true); mContainerView.setClickable(true); mZoomManager = new ZoomManager(mContext, this); @@ -1375,7 +1380,20 @@ import java.util.Map; public void evaluateJavaScript( String script, JavaScriptCallback callback) throws IllegalStateException { checkIsAlive(); - nativeEvaluateJavaScript(mNativeContentViewCore, script, callback); + nativeEvaluateJavaScript(mNativeContentViewCore, script, callback, false); + } + + /** + * Injects the passed Javascript code in the current page and evaluates it. + * If there is no page existing, a new one will be created. + * + * @param script The Javascript to execute. + * @throws IllegalStateException If the ContentView has been destroyed. + */ + public void evaluateJavaScriptEvenIfNotYetNavigated(String script) + throws IllegalStateException { + checkIsAlive(); + nativeEvaluateJavaScript(mNativeContentViewCore, script, null, true); } /** @@ -1657,6 +1675,15 @@ import java.util.Map; mScrolledAndZoomedFocusedEditableNode = false; } + /** + * @see View#onWindowFocusChanged(boolean) + */ + public void onWindowFocusChanged(boolean hasWindowFocus) { + if (!hasWindowFocus) { + mContentViewGestureHandler.onWindowFocusLost(); + } + } + public void onFocusChanged(boolean gainFocus) { if (!gainFocus) getContentViewClient().onImeStateChangeRequested(false); if (mNativeContentViewCore != 0) nativeSetFocus(mNativeContentViewCore, gainFocus); @@ -1860,17 +1887,32 @@ import java.util.Map; } } + /** + * Called by native side when the corresponding renderer crashes. Note that if a renderer is + * shared between tabs, this might be called multiple times while the tab is crashed. This is + * because the tabs sharing a renderer also share RenderProcessHost. When one of those tabs + * reloads and a new renderer is created for the shared RenderProcessHost, all tabs are notified + * in onRenderProcessSwap(), not only the one that reloads. If this renderer dies, all the other + * dead tabs are notified again. + * @param alreadyCrashed true iff this tab is already in crashed state but the shared renderer + * resurrected and died again since the last time this was called. + */ @SuppressWarnings("unused") @CalledByNative - private void onTabCrash() { + private void onTabCrash(boolean alreadyCrashed) { assert mPid != 0; - getContentViewClient().onRendererCrash(ChildProcessLauncher.isOomProtected(mPid)); + if (!alreadyCrashed) { + getContentViewClient().onRendererCrash(ChildProcessLauncher.isOomProtected(mPid)); + } mPid = 0; } private void handleTapOrPress( long timeMs, float xPix, float yPix, int isLongPressOrTap, boolean showPress) { - if (!mContainerView.isFocused()) mContainerView.requestFocus(); + if (mContainerView.isFocusable() && mContainerView.isFocusableInTouchMode() + && !mContainerView.isFocused()) { + mContainerView.requestFocus(); + } if (!mPopupZoomer.isShowing()) mPopupZoomer.setLastTouch(xPix, yPix); @@ -1905,6 +1947,10 @@ import java.util.Map; mZoomManager.updateMultiTouchSupport(supportsMultiTouchZoom); } + public void updateDoubleTapDragSupport(boolean supportsDoubleTapDrag) { + mContentViewGestureHandler.updateDoubleTapDragSupport(supportsDoubleTapDrag); + } + public void selectPopupMenuItems(int[] indices) { if (mNativeContentViewCore != 0) { nativeSelectPopupMenuItems(mNativeContentViewCore, indices); @@ -2403,9 +2449,18 @@ import java.util.Map; mEndHandlePoint.setLocalDip(x1, y1); } + boolean wereSelectionHandlesShowing = getSelectionHandleController().isShowing(); + getSelectionHandleController().onSelectionChanged(anchorDir, focusDir); updateHandleScreenPositions(); mHasSelection = true; + + if (!wereSelectionHandlesShowing && getSelectionHandleController().isShowing()) { + // TODO(cjhopman): Remove this when there is a better signal that long press caused + // a selection. See http://crbug.com/150151. + mContainerView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); + } + } else { mUnselectAllOnActionModeDismiss = false; hideSelectActionBar(); @@ -2472,15 +2527,19 @@ import java.util.Map; @SuppressWarnings("unused") @CalledByNative private void onWebContentsConnected() { - if (mImeAdapter != null && - !mImeAdapter.isNativeImeAdapterAttached() && mNativeContentViewCore != 0) { - mImeAdapter.attach(nativeGetNativeImeAdapter(mNativeContentViewCore)); - } + attachImeAdapter(); } @SuppressWarnings("unused") @CalledByNative private void onWebContentsSwapped() { + attachImeAdapter(); + } + + /** + * Attaches the native ImeAdapter object to the java ImeAdapter to allow communication via JNI. + */ + public void attachImeAdapter() { if (mImeAdapter != null && mNativeContentViewCore != 0) { mImeAdapter.attach(nativeGetNativeImeAdapter(mNativeContentViewCore)); } @@ -2751,14 +2810,23 @@ import java.util.Map; * If native accessibility (not script injection) is enabled, and if this is * running on JellyBean or later, returns an AccessibilityNodeProvider that * implements native accessibility for this view. Returns null otherwise. + * Lazily initializes native accessibility here if it's allowed. * @return The AccessibilityNodeProvider, if available, or null otherwise. */ public AccessibilityNodeProvider getAccessibilityNodeProvider() { if (mBrowserAccessibilityManager != null) { return mBrowserAccessibilityManager.getAccessibilityNodeProvider(); - } else { - return null; } + + if (mNativeAccessibilityAllowed && + !mNativeAccessibilityEnabled && + mNativeContentViewCore != 0 && + Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { + mNativeAccessibilityEnabled = true; + nativeSetAccessibilityEnabled(mNativeContentViewCore, true); + } + + return null; } /** @@ -2845,29 +2913,20 @@ import java.util.Map; * Turns browser accessibility on or off. * If |state| is |false|, this turns off both native and injected accessibility. * Otherwise, if accessibility script injection is enabled, this will enable the injected - * accessibility scripts, and if it is disabled this will enable the native accessibility. + * accessibility scripts. Native accessibility is enabled on demand. */ public void setAccessibilityState(boolean state) { - boolean injectedAccessibility = false; - boolean nativeAccessibility = false; - if (state) { - if (isDeviceAccessibilityScriptInjectionEnabled()) { - injectedAccessibility = true; - } else { - nativeAccessibility = true; - } + if (!state) { + setInjectedAccessibility(false); + return; } - setInjectedAccessibility(injectedAccessibility); - setNativeAccessibilityState(nativeAccessibility); - } - /** - * Enable or disable native accessibility features. - */ - public void setNativeAccessibilityState(boolean enabled) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { - nativeSetAccessibilityEnabled(mNativeContentViewCore, enabled); + if (isDeviceAccessibilityScriptInjectionEnabled()) { + setInjectedAccessibility(true); + return; } + + mNativeAccessibilityAllowed = true; } /** @@ -3121,7 +3180,7 @@ import java.util.Map; private native void nativeClearHistory(int nativeContentViewCoreImpl); private native void nativeEvaluateJavaScript(int nativeContentViewCoreImpl, - String script, JavaScriptCallback callback); + String script, JavaScriptCallback callback, boolean startRenderer); private native int nativeGetNativeImeAdapter(int nativeContentViewCoreImpl); diff --git a/chromium/content/public/android/java/src/org/chromium/content/browser/ContentViewGestureHandler.java b/chromium/content/public/android/java/src/org/chromium/content/browser/ContentViewGestureHandler.java index 053aa9a48a3..ddf433e3ac2 100644 --- a/chromium/content/public/android/java/src/org/chromium/content/browser/ContentViewGestureHandler.java +++ b/chromium/content/public/android/java/src/org/chromium/content/browser/ContentViewGestureHandler.java @@ -9,6 +9,7 @@ import android.os.Bundle; import android.os.Handler; import android.os.SystemClock; import android.util.Log; +import android.view.InputDevice; import android.view.MotionEvent; import android.view.ViewConfiguration; @@ -143,6 +144,10 @@ class ContentViewGestureHandler implements LongPressDelegate { // Whether input events are delivered right before vsync. private final boolean mInputEventsDeliveredAtVSync; + // Keeps track of the last long press event, if we end up opening a context menu, we would need + // to potentially use the event to send GESTURE_SHOW_PRESS_CANCEL to remove ::active styling + private MotionEvent mLastLongPressEvent; + static final int GESTURE_SHOW_PRESSED_STATE = 0; static final int GESTURE_DOUBLE_TAP = 1; static final int GESTURE_SINGLE_TAP_UP = 2; @@ -176,6 +181,7 @@ class ContentViewGestureHandler implements LongPressDelegate { static final int DOUBLE_TAP_DRAG_MODE_NONE = 0; static final int DOUBLE_TAP_DRAG_MODE_DETECTION_IN_PROGRESS = 1; static final int DOUBLE_TAP_DRAG_MODE_ZOOM = 2; + static final int DOUBLE_TAP_DRAG_MODE_DISABLED = 3; private class TouchEventTimeoutHandler implements Runnable { private static final int TOUCH_EVENT_TIMEOUT = 200; @@ -336,9 +342,9 @@ class ContentViewGestureHandler implements LongPressDelegate { void setTestDependencies( LongPressDetector longPressDetector, GestureDetector gestureDetector, OnGestureListener listener) { - mLongPressDetector = longPressDetector; - mGestureDetector = gestureDetector; - mListener = listener; + if (longPressDetector != null) mLongPressDetector = longPressDetector; + if (gestureDetector != null) mGestureDetector = gestureDetector; + if (listener != null) mListener = listener; } private void initGestureDetectors(final Context context) { @@ -510,6 +516,7 @@ class ContentViewGestureHandler implements LongPressDelegate { @Override public boolean onDoubleTapEvent(MotionEvent e) { + if (isDoubleTapDragDisabled()) return false; switch (e.getActionMasked()) { case MotionEvent.ACTION_DOWN: sendShowPressCancelIfNecessary(e); @@ -543,7 +550,7 @@ class ContentViewGestureHandler implements LongPressDelegate { pinchBy(e.getEventTime(), Math.round(mDoubleTapDragZoomAnchorX), Math.round(mDoubleTapDragZoomAnchorY), - (float) Math.pow(dy < 0 ? + (float) Math.pow(dy > 0 ? 1.0f - DOUBLE_TAP_DRAG_ZOOM_SPEED : 1.0f + DOUBLE_TAP_DRAG_ZOOM_SPEED, Math.abs(dy * mPxToDp))); @@ -569,8 +576,9 @@ class ContentViewGestureHandler implements LongPressDelegate { @Override public void onLongPress(MotionEvent e) { if (!mZoomManager.isScaleGestureDetectionInProgress() && - mDoubleTapDragMode == DOUBLE_TAP_DRAG_MODE_NONE) { - sendShowPressCancelIfNecessary(e); + (mDoubleTapDragMode == DOUBLE_TAP_DRAG_MODE_NONE || + isDoubleTapDragDisabled())) { + mLastLongPressEvent = e; sendMotionEventAsGesture(GESTURE_LONG_PRESS, e, null); } } @@ -664,6 +672,7 @@ class ContentViewGestureHandler implements LongPressDelegate { * to send. This argument is an optional and can be null. */ void endDoubleTapDragMode(MotionEvent event) { + if (isDoubleTapDragDisabled()) return; if (mDoubleTapDragMode == DOUBLE_TAP_DRAG_MODE_ZOOM) { if (event == null) event = obtainActionCancelMotionEvent(); pinchEnd(event.getEventTime()); @@ -796,6 +805,15 @@ class ContentViewGestureHandler implements LongPressDelegate { } } + /** + * Handle content view losing focus -- ensure that any remaining active state is removed. + */ + void onWindowFocusLost() { + if (mLongPressDetector.isInLongPress() && mLastLongPressEvent != null) { + sendShowPressCancelIfNecessary(mLastLongPressEvent); + } + } + private MotionEvent obtainActionCancelMotionEvent() { return MotionEvent.obtain( SystemClock.uptimeMillis(), @@ -810,16 +828,11 @@ class ContentViewGestureHandler implements LongPressDelegate { * FrameLoader::transitionToCommitted iff the page ever had touch handlers. */ void resetGestureHandlers() { - { - MotionEvent me = obtainActionCancelMotionEvent(); - mGestureDetector.onTouchEvent(me); - me.recycle(); - } - { - MotionEvent me = obtainActionCancelMotionEvent(); - mZoomManager.processTouchEvent(me); - me.recycle(); - } + MotionEvent me = obtainActionCancelMotionEvent(); + me.setSource(InputDevice.SOURCE_CLASS_POINTER); + mGestureDetector.onTouchEvent(me); + mZoomManager.processTouchEvent(me); + me.recycle(); mLongPressDetector.cancelLongPress(); } @@ -1081,6 +1094,7 @@ class ContentViewGestureHandler implements LongPressDelegate { if (sendMotionEventAsGesture(GESTURE_SHOW_PRESS_CANCEL, e, null)) { mShowPressIsCalled = false; + mLastLongPressEvent = null; } } @@ -1148,4 +1162,15 @@ class ContentViewGestureHandler implements LongPressDelegate { boolean hasScheduledTouchTimeoutEventForTesting() { return mTouchEventTimeoutHandler.hasScheduledTimeoutEventForTesting(); } + + public void updateDoubleTapDragSupport(boolean supportDoubleTapDrag) { + assert (mDoubleTapDragMode == DOUBLE_TAP_DRAG_MODE_DISABLED || + mDoubleTapDragMode == DOUBLE_TAP_DRAG_MODE_NONE); + mDoubleTapDragMode = supportDoubleTapDrag ? + DOUBLE_TAP_DRAG_MODE_NONE : DOUBLE_TAP_DRAG_MODE_DISABLED; + } + + private boolean isDoubleTapDragDisabled() { + return mDoubleTapDragMode == DOUBLE_TAP_DRAG_MODE_DISABLED; + } } diff --git a/chromium/content/public/android/java/src/org/chromium/content/browser/MediaResourceGetter.java b/chromium/content/public/android/java/src/org/chromium/content/browser/MediaResourceGetter.java index 5d0de5ad95b..cab9de296b5 100644 --- a/chromium/content/public/android/java/src/org/chromium/content/browser/MediaResourceGetter.java +++ b/chromium/content/public/android/java/src/org/chromium/content/browser/MediaResourceGetter.java @@ -5,6 +5,7 @@ package org.chromium.content.browser; import android.content.Context; +import android.content.pm.PackageManager; import android.media.MediaMetadataRetriever; import android.net.ConnectivityManager; import android.net.NetworkInfo; @@ -63,6 +64,12 @@ class MediaResourceGetter { ConnectivityManager mConnectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); if (mConnectivityManager != null) { + if (context.checkCallingOrSelfPermission( + android.Manifest.permission.ACCESS_NETWORK_STATE) != + PackageManager.PERMISSION_GRANTED) { + return new MediaMetadata(0, 0, 0, false); + } + NetworkInfo info = mConnectivityManager.getActiveNetworkInfo(); if (info == null) { return new MediaMetadata(durationInMilliseconds, width, height, success); diff --git a/chromium/content/public/android/java/src/org/chromium/content/browser/SelectActionModeCallback.java b/chromium/content/public/android/java/src/org/chromium/content/browser/SelectActionModeCallback.java index 4ff58bd6bdc..6053448f554 100644 --- a/chromium/content/public/android/java/src/org/chromium/content/browser/SelectActionModeCallback.java +++ b/chromium/content/public/android/java/src/org/chromium/content/browser/SelectActionModeCallback.java @@ -4,6 +4,7 @@ package org.chromium.content.browser; +import android.app.Activity; import android.app.SearchManager; import android.content.ClipboardManager; import android.content.Context; @@ -27,11 +28,15 @@ public class SelectActionModeCallback implements ActionMode.Callback { private static final int CUT_ATTR_INDEX = 1; private static final int COPY_ATTR_INDEX = 2; private static final int PASTE_ATTR_INDEX = 3; + private static final int SHARE_ATTR_INDEX = 4; + private static final int WEB_SEARCH_ATTR_INDEX = 5; private static final int[] ACTION_MODE_ATTRS = { android.R.attr.actionModeSelectAllDrawable, android.R.attr.actionModeCutDrawable, android.R.attr.actionModeCopyDrawable, android.R.attr.actionModePasteDrawable, + R.attr.action_mode_share_drawable, + R.attr.action_mode_web_search_drawable }; private static final int ID_SELECTALL = 0; @@ -124,7 +129,8 @@ public class SelectActionModeCallback implements ActionMode.Callback { } private void createActionMenu(ActionMode mode, Menu menu) { - TypedArray styledAttributes = getContext().obtainStyledAttributes(ACTION_MODE_ATTRS); + TypedArray styledAttributes = getContext().obtainStyledAttributes( + R.style.ContentActionBar, ACTION_MODE_ATTRS); menu.add(Menu.NONE, ID_SELECTALL, Menu.NONE, android.R.string.selectAll). setAlphabeticShortcut('a'). @@ -157,14 +163,14 @@ public class SelectActionModeCallback implements ActionMode.Callback { if (!mEditable) { if (isShareHandlerAvailable()) { menu.add(Menu.NONE, ID_SHARE, Menu.NONE, R.string.actionbar_share). - setIcon(R.drawable.ic_menu_share_holo_light). + setIcon(styledAttributes.getResourceId(SHARE_ATTR_INDEX, 0)). setShowAsAction( MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT); } if (!mIncognito && isWebSearchAvailable()) { menu.add(Menu.NONE, ID_SEARCH, Menu.NONE, R.string.actionbar_web_search). - setIcon(R.drawable.ic_menu_search_holo_light). + setIcon(styledAttributes.getResourceId(WEB_SEARCH_ATTR_INDEX, 0)). setShowAsAction( MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT); } @@ -212,6 +218,9 @@ public class SelectActionModeCallback implements ActionMode.Callback { i.putExtra(SearchManager.EXTRA_NEW_SEARCH, true); i.putExtra(SearchManager.QUERY, selection); i.putExtra(Browser.EXTRA_APPLICATION_ID, getContext().getPackageName()); + if (!(getContext() instanceof Activity)) { + i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + } try { getContext().startActivity(i); } catch (android.content.ActivityNotFoundException ex) { diff --git a/chromium/content/public/android/java/src/org/chromium/content/browser/accessibility/BrowserAccessibilityManager.java b/chromium/content/public/android/java/src/org/chromium/content/browser/accessibility/BrowserAccessibilityManager.java index f03ba9b79e7..2180b480e7f 100644 --- a/chromium/content/public/android/java/src/org/chromium/content/browser/accessibility/BrowserAccessibilityManager.java +++ b/chromium/content/public/android/java/src/org/chromium/content/browser/accessibility/BrowserAccessibilityManager.java @@ -268,13 +268,11 @@ public class BrowserAccessibilityManager { @CalledByNative private void handleTextSelectionChanged(int id) { - sendAccessibilityEvent(id, AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED); sendAccessibilityEvent(id, AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED); } @CalledByNative private void handleEditableTextChanged(int id) { - sendAccessibilityEvent(id, AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED); sendAccessibilityEvent(id, AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED); } diff --git a/chromium/content/public/android/java/src/org/chromium/content/browser/input/HandleView.java b/chromium/content/public/android/java/src/org/chromium/content/browser/input/HandleView.java index a220894fd80..88a6deaefea 100644 --- a/chromium/content/public/android/java/src/org/chromium/content/browser/input/HandleView.java +++ b/chromium/content/public/android/java/src/org/chromium/content/browser/input/HandleView.java @@ -152,16 +152,20 @@ public class HandleView extends View { mDrawable.getIntrinsicHeight()); } + private void updateContainerPosition() { + final int[] coords = mTempCoords; + mParent.getLocationInWindow(coords); + mContainerPositionX = coords[0] + mPositionX; + mContainerPositionY = coords[1] + mPositionY; + } + void show() { if (!isPositionVisible()) { hide(); return; } mContainer.setContentView(this); - final int[] coords = mTempCoords; - mParent.getLocationInWindow(coords); - mContainerPositionX = coords[0] + mPositionX; - mContainerPositionY = coords[1] + mPositionY; + updateContainerPosition(); mContainer.showAtLocation(mParent, 0, mContainerPositionX, mContainerPositionY); // Hide paste view when handle is moved on screen. @@ -261,6 +265,9 @@ public class HandleView extends View { @Override protected void onDraw(Canvas c) { updateAlpha(); + updateContainerPosition(); + mContainer.update(mContainerPositionX, mContainerPositionY, + getRight() - getLeft(), getBottom() - getTop()); mDrawable.setBounds(0, 0, getRight() - getLeft(), getBottom() - getTop()); mDrawable.draw(c); } diff --git a/chromium/content/public/android/java/src/org/chromium/content/browser/input/MonthPicker.java b/chromium/content/public/android/java/src/org/chromium/content/browser/input/MonthPicker.java index 3e06d75cf90..57cab667619 100644 --- a/chromium/content/public/android/java/src/org/chromium/content/browser/input/MonthPicker.java +++ b/chromium/content/public/android/java/src/org/chromium/content/browser/input/MonthPicker.java @@ -92,16 +92,16 @@ public class MonthPicker extends TwoFieldDatePicker { @Override - protected int getMaxPositionInYear() { - if (getYear() == getMaxDate().get(Calendar.YEAR)) { + protected int getMaxPositionInYear(int year) { + if (year == getMaxDate().get(Calendar.YEAR)) { return getMaxDate().get(Calendar.MONTH); } return MONTHS_NUMBER - 1; } @Override - protected int getMinPositionInYear() { - if (getYear() == getMinDate().get(Calendar.YEAR)) { + protected int getMinPositionInYear(int year) { + if (year == getMinDate().get(Calendar.YEAR)) { return getMinDate().get(Calendar.MONTH); } return 0; diff --git a/chromium/content/public/android/java/src/org/chromium/content/browser/input/SelectPopupDialog.java b/chromium/content/public/android/java/src/org/chromium/content/browser/input/SelectPopupDialog.java index d32266b0f44..360f9282883 100644 --- a/chromium/content/public/android/java/src/org/chromium/content/browser/input/SelectPopupDialog.java +++ b/chromium/content/public/android/java/src/org/chromium/content/browser/input/SelectPopupDialog.java @@ -8,6 +8,7 @@ import org.chromium.content.browser.ContentViewCore; import android.app.AlertDialog; import android.content.DialogInterface; +import android.content.res.TypedArray; import android.util.SparseBooleanArray; import android.view.View; import android.view.ViewGroup; @@ -17,6 +18,8 @@ import android.widget.ArrayAdapter; import android.widget.CheckedTextView; import android.widget.ListView; +import org.chromium.content.R; + /** * Handles the popup dialog for the <select> HTML tag support. */ @@ -24,6 +27,11 @@ public class SelectPopupDialog { // The currently showing popup dialog, null if none is showing. private static SelectPopupDialog sShownDialog; + private static final int[] SELECT_DIALOG_ATTRS = { + R.attr.select_dialog_multichoice, + R.attr.select_dialog_singlechoice + }; + // The dialog hosting the popup list view. private AlertDialog mListBoxPopup = null; @@ -48,9 +56,7 @@ public class SelectPopupDialog { private boolean mAreAllItemsEnabled; public SelectPopupArrayAdapter(String[] labels, int[] enabled, boolean multiple) { - super(mContentViewCore.getContext(), multiple ? - android.R.layout.select_dialog_multichoice : - android.R.layout.select_dialog_singlechoice, labels); + super(mContentViewCore.getContext(), getSelectDialogLayout(multiple), labels); mItemEnabled = enabled; mAreAllItemsEnabled = true; for (int item : mItemEnabled) { @@ -99,11 +105,21 @@ public class SelectPopupDialog { } } + private int getSelectDialogLayout(boolean isMultiChoice) { + int resource_id; + TypedArray styledAttributes = mContentViewCore.getContext().obtainStyledAttributes( + R.style.SelectPopupDialog, SELECT_DIALOG_ATTRS); + resource_id = styledAttributes.getResourceId(isMultiChoice ? 0 : 1, 0); + styledAttributes.recycle(); + return resource_id; + } + private SelectPopupDialog(ContentViewCore contentViewCore, String[] labels, int[] enabled, boolean multiple, int[] selected) { mContentViewCore = contentViewCore; final ListView listView = new ListView(mContentViewCore.getContext()); + listView.setCacheColorHint(0); AlertDialog.Builder b = new AlertDialog.Builder(mContentViewCore.getContext()) .setView(listView) .setCancelable(true) diff --git a/chromium/content/public/android/java/src/org/chromium/content/browser/input/TwoFieldDatePicker.java b/chromium/content/public/android/java/src/org/chromium/content/browser/input/TwoFieldDatePicker.java index 4eaa0b787cb..c6dfd616c38 100644 --- a/chromium/content/public/android/java/src/org/chromium/content/browser/input/TwoFieldDatePicker.java +++ b/chromium/content/public/android/java/src/org/chromium/content/browser/input/TwoFieldDatePicker.java @@ -67,8 +67,10 @@ public abstract class TwoFieldDatePicker extends FrameLayout { positionInYear = newVal; if (oldVal == picker.getMaxValue() && newVal == picker.getMinValue()) { year += 1; + positionInYear = getMinPositionInYear(year); } else if (oldVal == picker.getMinValue() && newVal == picker.getMaxValue()) { year -=1; + positionInYear = getMaxPositionInYear(year); } } else if (picker == mYearSpinner) { year = newVal; @@ -188,9 +190,9 @@ public abstract class TwoFieldDatePicker extends FrameLayout { protected abstract int getMinYear(); - protected abstract int getMaxPositionInYear(); + protected abstract int getMaxPositionInYear(int year); - protected abstract int getMinPositionInYear(); + protected abstract int getMinPositionInYear(int year); protected Calendar getMaxDate() { return mMaxDate; @@ -219,8 +221,8 @@ public abstract class TwoFieldDatePicker extends FrameLayout { mPositionInYearSpinner.setDisplayedValues(null); // set the spinner ranges respecting the min and max dates - mPositionInYearSpinner.setMinValue(getMinPositionInYear()); - mPositionInYearSpinner.setMaxValue(getMaxPositionInYear()); + mPositionInYearSpinner.setMinValue(getMinPositionInYear(getYear())); + mPositionInYearSpinner.setMaxValue(getMaxPositionInYear(getYear())); mPositionInYearSpinner.setWrapSelectorWheel( !mCurrentDate.equals(mMinDate) && !mCurrentDate.equals(mMaxDate)); diff --git a/chromium/content/public/android/java/src/org/chromium/content/browser/input/WeekPicker.java b/chromium/content/public/android/java/src/org/chromium/content/browser/input/WeekPicker.java index 117793b1978..efca4763a29 100644 --- a/chromium/content/public/android/java/src/org/chromium/content/browser/input/WeekPicker.java +++ b/chromium/content/public/android/java/src/org/chromium/content/browser/input/WeekPicker.java @@ -76,9 +76,9 @@ public class WeekPicker extends TwoFieldDatePicker { } } - private int getNumberOfWeeks() { + private int getNumberOfWeeks(int year) { // Create a date in the middle of the year, where the week year matches the year. - Calendar date = createDateFromWeek(getYear(), 20); + Calendar date = createDateFromWeek(year, 20); return date.getActualMaximum(Calendar.WEEK_OF_YEAR); } @@ -113,16 +113,16 @@ public class WeekPicker extends TwoFieldDatePicker { } @Override - protected int getMaxPositionInYear() { - if (getYear() == getISOWeekYearForDate(getMaxDate())) { + protected int getMaxPositionInYear(int year) { + if (year == getISOWeekYearForDate(getMaxDate())) { return getWeekForDate(getMaxDate()); } - return getNumberOfWeeks(); + return getNumberOfWeeks(year); } @Override - protected int getMinPositionInYear() { - if (getYear() == getISOWeekYearForDate(getMinDate())) { + protected int getMinPositionInYear(int year) { + if (year == getISOWeekYearForDate(getMinDate())) { return getWeekForDate(getMinDate()); } return 1; diff --git a/chromium/content/public/android/javatests/src/org/chromium/content/browser/ContentViewGestureHandlerTest.java b/chromium/content/public/android/javatests/src/org/chromium/content/browser/ContentViewGestureHandlerTest.java index 2647b3a2f59..ce63defa32c 100644 --- a/chromium/content/public/android/javatests/src/org/chromium/content/browser/ContentViewGestureHandlerTest.java +++ b/chromium/content/public/android/javatests/src/org/chromium/content/browser/ContentViewGestureHandlerTest.java @@ -639,6 +639,55 @@ public class ContentViewGestureHandlerTest extends InstrumentationTestCase { } /** + * Verify that a show pressed state gesture followed by a long press followed by + * the focus + * loss in the window due to context menu cancels show pressed. + * @throws Exception + */ + @SmallTest + @Feature({"Gestures"}) + public void testShowPressCancelOnWindowFocusLost() throws Exception { + final long time = SystemClock.uptimeMillis(); + GestureRecordingMotionEventDelegate mockDelegate = + new GestureRecordingMotionEventDelegate(); + mGestureHandler = new ContentViewGestureHandler( + getInstrumentation().getTargetContext(), mockDelegate, + new MockZoomManager(getInstrumentation().getTargetContext(), null), + ContentViewCore.INPUT_EVENTS_DELIVERED_AT_VSYNC); + mLongPressDetector = new LongPressDetector( + getInstrumentation().getTargetContext(), mGestureHandler); + mGestureHandler.setTestDependencies(mLongPressDetector, null, null); + + MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, time, time); + mGestureHandler.onTouchEvent(event); + + mGestureHandler.sendShowPressedStateGestureForTesting(); + assertEquals("A show pressed state event should have been sent", + ContentViewGestureHandler.GESTURE_SHOW_PRESSED_STATE, + mockDelegate.mMostRecentGestureEvent.mType); + assertEquals("Only showPressedState should have been sent", + 1, mockDelegate.mGestureTypeList.size()); + + mLongPressDetector.startLongPressTimerIfNeeded(event); + mLongPressDetector.sendLongPressGestureForTest(); + + assertEquals("Only should have sent only LONG_PRESS event", + 2, mockDelegate.mGestureTypeList.size()); + assertEquals("Should have a long press event next", + ContentViewGestureHandler.GESTURE_LONG_PRESS, + mockDelegate.mGestureTypeList.get(1).intValue()); + + // The long press triggers window focus loss by opening a context menu + mGestureHandler.onWindowFocusLost(); + + assertEquals("Only should have sent only GESTURE_SHOW_PRESS_CANCEL event", + 3, mockDelegate.mGestureTypeList.size()); + assertEquals("Should have a long press event next", + ContentViewGestureHandler.GESTURE_SHOW_PRESS_CANCEL, + mockDelegate.mGestureTypeList.get(2).intValue()); + } + + /** * Verify that a recent show pressed state gesture is canceled when scrolling begins. * @throws Exception */ @@ -890,6 +939,73 @@ public class ContentViewGestureHandlerTest extends InstrumentationTestCase { } /** + * Verify that double tap drag zoom feature is not invoked + * when it is disabled.. + * @throws Exception + */ + @SmallTest + @Feature({"Gestures"}) + public void testDoubleTapDragZoomNothingWhenDisabled() throws Exception { + final long downTime1 = SystemClock.uptimeMillis(); + final long downTime2 = downTime1 + 100; + + GestureRecordingMotionEventDelegate mockDelegate = + new GestureRecordingMotionEventDelegate(); + mGestureHandler = new ContentViewGestureHandler( + getInstrumentation().getTargetContext(), mockDelegate, + new MockZoomManager(getInstrumentation().getTargetContext(), null), + ContentViewCore.INPUT_EVENTS_DELIVERED_AT_VSYNC); + + mGestureHandler.updateDoubleTapDragSupport(false); + + MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime1, downTime1); + assertTrue(mGestureHandler.onTouchEvent(event)); + + event = MotionEvent.obtain( + downTime1, downTime1 + 5, MotionEvent.ACTION_UP, + FAKE_COORD_X, FAKE_COORD_Y, 0); + mGestureHandler.onTouchEvent(event); + + event = MotionEvent.obtain( + downTime2, downTime2, MotionEvent.ACTION_DOWN, + FAKE_COORD_X, FAKE_COORD_Y, 0); + assertTrue(mGestureHandler.onTouchEvent(event)); + + event = MotionEvent.obtain( + downTime2, downTime2 + 5, MotionEvent.ACTION_MOVE, + FAKE_COORD_X, FAKE_COORD_Y + 100, 0); + // As double tap and drag to zoom is disabled, we won't handle + // the move event. + assertFalse(mGestureHandler.onTouchEvent(event)); + + assertFalse("No GESTURE_SCROLL_START should have been sent", + mockDelegate.mGestureTypeList.contains( + ContentViewGestureHandler.GESTURE_SCROLL_START)); + assertTrue("No GESTURE_PINCH_BEGIN should have been sent", + ContentViewGestureHandler.GESTURE_PINCH_BEGIN != + mockDelegate.mMostRecentGestureEvent.mType); + + event = MotionEvent.obtain( + downTime2, downTime2 + 10, MotionEvent.ACTION_MOVE, + FAKE_COORD_X, FAKE_COORD_Y + 200, 0); + assertFalse(mGestureHandler.onTouchEvent(event)); + assertFalse("No GESTURE_SCROLL_BY should have been sent", + mockDelegate.mGestureTypeList.contains( + ContentViewGestureHandler.GESTURE_SCROLL_BY)); + assertTrue("No GESTURE_PINCH_BY should have been sent", + ContentViewGestureHandler.GESTURE_PINCH_BY != + mockDelegate.mMostRecentGestureEvent.mType); + + event = MotionEvent.obtain( + downTime2, downTime2 + 15, MotionEvent.ACTION_UP, + FAKE_COORD_X, FAKE_COORD_Y + 200, 0); + assertFalse(mGestureHandler.onTouchEvent(event)); + assertFalse("No GESTURE_PINCH_END should have been sent", + mockDelegate.mGestureTypeList.contains( + ContentViewGestureHandler.GESTURE_PINCH_END)); + } + + /** * Mock MotionEventDelegate that remembers the most recent gesture event. */ static class GestureRecordingMotionEventDelegate implements MotionEventDelegate { diff --git a/chromium/content/public/android/javatests/src/org/chromium/content/browser/ContentViewScrollingTest.java b/chromium/content/public/android/javatests/src/org/chromium/content/browser/ContentViewScrollingTest.java index 998f036d58a..d880a96b86b 100644 --- a/chromium/content/public/android/javatests/src/org/chromium/content/browser/ContentViewScrollingTest.java +++ b/chromium/content/public/android/javatests/src/org/chromium/content/browser/ContentViewScrollingTest.java @@ -26,6 +26,15 @@ public class ContentViewScrollingTest extends ContentShellTestBase { "<body>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</body>" + "</html>"); + private void assertWaitForPageScaleFactor(final float scale) throws InterruptedException { + assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + @Override + public boolean isSatisfied() { + return getContentViewCore().getScale() == scale; + } + })); + } + private void assertWaitForScroll(final boolean hugLeft, final boolean hugTop) throws InterruptedException { assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { @@ -70,7 +79,7 @@ public class ContentViewScrollingTest extends ContentShellTestBase { launchContentShellWithUrl(LARGE_PAGE); assertTrue("Page failed to load", waitForActiveShellToBeDoneLoading()); - assertWaitForPageScaleFactorMatch(1.0f); + assertWaitForPageScaleFactor(1.0f); assertEquals(0, getContentViewCore().getNativeScrollXForTest()); assertEquals(0, getContentViewCore().getNativeScrollYForTest()); diff --git a/chromium/content/public/android/javatests/src/org/chromium/content/browser/input/ImeTest.java b/chromium/content/public/android/javatests/src/org/chromium/content/browser/input/ImeTest.java index e4c1a5f727f..a12007f3cc8 100644 --- a/chromium/content/public/android/javatests/src/org/chromium/content/browser/input/ImeTest.java +++ b/chromium/content/public/android/javatests/src/org/chromium/content/browser/input/ImeTest.java @@ -61,7 +61,7 @@ public class ImeTest extends ContentShellTestBase { mContentView = getActivity().getActiveContentView(); mCallbackContainer = new TestCallbackHelperContainer(mContentView); // TODO(aurimas) remove this wait once crbug.com/179511 is fixed. - assertWaitForPageScaleFactorMatch(1); + assertWaitForPageScaleFactor(1); DOMUtils.clickNode(this, mContentView, mCallbackContainer, "input_text"); assertWaitForKeyboardStatus(true); @@ -286,6 +286,17 @@ public class ImeTest extends ContentShellTestBase { }); } + + + private void assertWaitForPageScaleFactor(final float scale) throws InterruptedException { + assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + @Override + public boolean isSatisfied() { + return getContentViewCore().getScale() == scale; + } + })); + } + private void assertWaitForKeyboardStatus(final boolean show) throws InterruptedException { assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { @Override diff --git a/chromium/content/public/android/javatests/src/org/chromium/content/browser/input/InsertionHandleTest.java b/chromium/content/public/android/javatests/src/org/chromium/content/browser/input/InsertionHandleTest.java index 91e61242d71..d2697b711f1 100644 --- a/chromium/content/public/android/javatests/src/org/chromium/content/browser/input/InsertionHandleTest.java +++ b/chromium/content/public/android/javatests/src/org/chromium/content/browser/input/InsertionHandleTest.java @@ -87,12 +87,8 @@ public class InsertionHandleTest extends ContentShellTestBase { } - /** - * @MediumTest - * @Feature({"TextSelection", "TextInput", "Main"}) - * http://crbug.com/169648 - */ - @DisabledTest + @MediumTest + @Feature({"TextSelection", "TextInput", "Main"}) public void testKeyEventHidesHandle() throws Throwable { launchWithUrl(TEXTAREA_DATA_URL); clickNodeToShowInsertionHandle(TEXTAREA_ID); diff --git a/chromium/content/public/browser/android/synchronous_compositor_client.h b/chromium/content/public/browser/android/synchronous_compositor_client.h index dbd6d33bdf4..bfd647b931d 100644 --- a/chromium/content/public/browser/android/synchronous_compositor_client.h +++ b/chromium/content/public/browser/android/synchronous_compositor_client.h @@ -27,7 +27,8 @@ class SynchronousCompositorClient { // See LayerScrollOffsetDelegate for details. virtual void SetTotalRootLayerScrollOffset(gfx::Vector2dF new_value) = 0; virtual gfx::Vector2dF GetTotalRootLayerScrollOffset() = 0; - virtual void DidOverscroll(gfx::Vector2dF latest_overscroll_delta, + virtual void DidOverscroll(gfx::Vector2dF accumulated_overscroll, + gfx::Vector2dF latest_overscroll_delta, gfx::Vector2dF current_fling_velocity) = 0; // When true, should periodically call diff --git a/chromium/content/public/browser/browser_plugin_guest_delegate.h b/chromium/content/public/browser/browser_plugin_guest_delegate.h index 73b477040cd..11facb9b5ed 100644 --- a/chromium/content/public/browser/browser_plugin_guest_delegate.h +++ b/chromium/content/public/browser/browser_plugin_guest_delegate.h @@ -11,7 +11,6 @@ #include "base/values.h" #include "content/common/content_export.h" #include "content/public/common/browser_plugin_permission_type.h" -#include "ui/gfx/size.h" namespace content { @@ -58,10 +57,6 @@ class CONTENT_EXPORT BrowserPluginGuestDelegate { BrowserPluginPermissionType permission_type, const base::DictionaryValue& request_info, const PermissionResponseCallback& callback); - - // Notifies that the content size of the guest has changed in autosize mode. - virtual void SizeChanged(const gfx::Size& old_size, - const gfx::Size& new_size) {} }; } // namespace content diff --git a/chromium/content/public/browser/content_browser_client.cc b/chromium/content/public/browser/content_browser_client.cc index c2bf137b077..4337c2da772 100644 --- a/chromium/content/public/browser/content_browser_client.cc +++ b/chromium/content/public/browser/content_browser_client.cc @@ -208,6 +208,7 @@ WebKit::WebNotificationPresenter::Permission bool ContentBrowserClient::CanCreateWindow( const GURL& opener_url, + const GURL& opener_top_level_frame_url, const GURL& source_origin, WindowContainerType container_type, const GURL& target_url, diff --git a/chromium/content/public/browser/content_browser_client.h b/chromium/content/public/browser/content_browser_client.h index 21687691706..56c01775e65 100644 --- a/chromium/content/public/browser/content_browser_client.h +++ b/chromium/content/public/browser/content_browser_client.h @@ -451,6 +451,7 @@ class CONTENT_EXPORT ContentBrowserClient { // the window that is created should be scriptable/in the same process. // This is called on the IO thread. virtual bool CanCreateWindow(const GURL& opener_url, + const GURL& opener_top_level_frame_url, const GURL& source_origin, WindowContainerType container_type, const GURL& target_url, diff --git a/chromium/content/public/browser/web_contents_delegate.cc b/chromium/content/public/browser/web_contents_delegate.cc index 47e30b2acba..964206d31e1 100644 --- a/chromium/content/public/browser/web_contents_delegate.cc +++ b/chromium/content/public/browser/web_contents_delegate.cc @@ -127,8 +127,11 @@ bool WebContentsDelegate::ShouldCreateWebContents( WindowContainerType window_container_type, const string16& frame_name, const GURL& target_url, - const std::string& partition_id, - SessionStorageNamespace* session_storage_namespace) { + const Referrer& referrer, + WindowOpenDisposition disposition, + const WebKit::WebWindowFeatures& features, + bool user_gesture, + bool opener_suppressed) { return true; } @@ -146,6 +149,13 @@ content::ColorChooser* WebContentsDelegate::OpenColorChooser( return NULL; } +void WebContentsDelegate::RequestMediaAccessPermission( + WebContents* web_contents, + const MediaStreamRequest& request, + const MediaResponseCallback& callback) { + callback.Run(MediaStreamDevices(), scoped_ptr<MediaStreamUI>()); +} + bool WebContentsDelegate::RequestPpapiBrokerPermission( WebContents* web_contents, const GURL& url, diff --git a/chromium/content/public/browser/web_contents_delegate.h b/chromium/content/public/browser/web_contents_delegate.h index 69ac871c85e..aa1bb4e3472 100644 --- a/chromium/content/public/browser/web_contents_delegate.h +++ b/chromium/content/public/browser/web_contents_delegate.h @@ -37,7 +37,6 @@ class DownloadItem; class JavaScriptDialogManager; class PageState; class RenderViewHost; -class SessionStorageNamespace; class WebContents; class WebContentsImpl; struct ContextMenuParams; @@ -301,8 +300,11 @@ class CONTENT_EXPORT WebContentsDelegate { WindowContainerType window_container_type, const string16& frame_name, const GURL& target_url, - const std::string& partition_id, - SessionStorageNamespace* session_storage_namespace); + const Referrer& referrer, + WindowOpenDisposition disposition, + const WebKit::WebWindowFeatures& features, + bool user_gesture, + bool opener_suppressed); // Notifies the delegate about the creation of a new WebContents. This // typically happens when popups are created. @@ -422,7 +424,7 @@ class CONTENT_EXPORT WebContentsDelegate { virtual void RequestMediaAccessPermission( WebContents* web_contents, const MediaStreamRequest& request, - const MediaResponseCallback& callback) {} + const MediaResponseCallback& callback); // Requests permission to access the PPAPI broker. The delegate should return // true and call the passed in |callback| with the result, or return false diff --git a/chromium/content/public/common/common_param_traits_macros.h b/chromium/content/public/common/common_param_traits_macros.h index a77c4c4ec70..9b5226e2116 100644 --- a/chromium/content/public/common/common_param_traits_macros.h +++ b/chromium/content/public/common/common_param_traits_macros.h @@ -201,7 +201,11 @@ IPC_STRUCT_TRAITS_BEGIN(WebPreferences) IPC_STRUCT_TRAITS_MEMBER(user_gesture_required_for_media_playback) IPC_STRUCT_TRAITS_MEMBER(default_video_poster_url) IPC_STRUCT_TRAITS_MEMBER(support_deprecated_target_density_dpi) + IPC_STRUCT_TRAITS_MEMBER(use_legacy_background_size_shorthand_behavior) + IPC_STRUCT_TRAITS_MEMBER(wide_viewport_quirk) IPC_STRUCT_TRAITS_MEMBER(use_wide_viewport) + IPC_STRUCT_TRAITS_MEMBER(viewport_meta_layout_size_quirk) + IPC_STRUCT_TRAITS_MEMBER(viewport_meta_zero_values_quirk) #endif IPC_STRUCT_TRAITS_END() diff --git a/chromium/content/public/common/content_switches.cc b/chromium/content/public/common/content_switches.cc index 63e94dfdc90..5169ba47de4 100644 --- a/chromium/content/public/common/content_switches.cc +++ b/chromium/content/public/common/content_switches.cc @@ -531,6 +531,11 @@ const char kEnableWebMIDI[] = "enable-web-midi"; // Enable WebRTC to open TCP server sockets. const char kEnableWebRtcTcpServerSocket[] = "enable-webrtc-tcp-server-socket"; +// Enables experimental features for the geolocation API. +// Current features: +// - CoreLocation support for Mac OS X 10.6 +const char kExperimentalLocationFeatures[] = "experimental-location-features"; + // Load NPAPI plugins from the specified directory. const char kExtraPluginDir[] = "extra-plugin-dir"; @@ -777,10 +782,6 @@ const char kTestingFixedHttpsPort[] = "testing-fixed-https-port"; // Runs the security test for the renderer sandbox. const char kTestSandbox[] = "test-sandbox"; -// Enables not sending touch events to renderer while scrolling. -const char kNoTouchToRendererWhileScrolling[] = - "no-touch-to-renderer-while-scrolling"; - // Causes TRACE_EVENT flags to be recorded from startup. Optionally, can // specify the specific trace categories to include (e.g. // --trace-startup=base,net) otherwise, all events are recorded. Setting this @@ -872,9 +873,6 @@ const char kEnableWebRtcAecRecordings[] = "enable-webrtc-aec-recordings"; // Enables HW decode acceleration for WebRTC. const char kEnableWebRtcHWDecoding[] = "enable-webrtc-hw-decoding"; -// Enables HW encode acceleration for WebRTC. -const char kEnableWebRtcHWEncoding[] = "enable-webrtc-hw-encoding"; - #endif #if defined(OS_ANDROID) diff --git a/chromium/content/public/common/content_switches.h b/chromium/content/public/common/content_switches.h index c468139f903..949400af1b9 100644 --- a/chromium/content/public/common/content_switches.h +++ b/chromium/content/public/common/content_switches.h @@ -159,6 +159,7 @@ extern const char kEnableWebAnimationsSVG[]; CONTENT_EXPORT extern const char kEnableWebGLDraftExtensions[]; extern const char kEnableWebMIDI[]; extern const char kEnableWebRtcTcpServerSocket[]; +CONTENT_EXPORT extern const char kExperimentalLocationFeatures[]; CONTENT_EXPORT extern const char kExtraPluginDir[]; CONTENT_EXPORT extern const char kForceCompositingMode[]; extern const char kForceFieldTrials[]; @@ -223,7 +224,6 @@ extern const char kTapDownDeferralTimeMs[]; CONTENT_EXPORT extern const char kTestingFixedHttpPort[]; CONTENT_EXPORT extern const char kTestingFixedHttpsPort[]; CONTENT_EXPORT extern const char kTestSandbox[]; -CONTENT_EXPORT extern const char kNoTouchToRendererWhileScrolling[]; extern const char kTraceStartup[]; extern const char kTraceStartupDuration[]; extern const char kTraceStartupFile[]; @@ -248,7 +248,6 @@ CONTENT_EXPORT extern const char kDisableDeviceEnumeration[]; CONTENT_EXPORT extern const char kEnableSCTPDataChannels[]; extern const char kEnableWebRtcAecRecordings[]; extern const char kEnableWebRtcHWDecoding[]; -extern const char kEnableWebRtcHWEncoding[]; #endif #if defined(OS_ANDROID) diff --git a/chromium/content/public/common/renderer_preferences.h b/chromium/content/public/common/renderer_preferences.h index bc5447a3e4f..0f141d21cc4 100644 --- a/chromium/content/public/common/renderer_preferences.h +++ b/chromium/content/public/common/renderer_preferences.h @@ -40,8 +40,9 @@ enum RendererPreferencesSubpixelRenderingEnum { enum TapMultipleTargetsStrategy { TAP_MULTIPLE_TARGETS_STRATEGY_ZOOM = 0, TAP_MULTIPLE_TARGETS_STRATEGY_POPUP, + TAP_MULTIPLE_TARGETS_STRATEGY_NONE, - TAP_MULTIPLE_TARGETS_STRATEGY_MAX = TAP_MULTIPLE_TARGETS_STRATEGY_POPUP, + TAP_MULTIPLE_TARGETS_STRATEGY_MAX = TAP_MULTIPLE_TARGETS_STRATEGY_NONE, }; struct CONTENT_EXPORT RendererPreferences { diff --git a/chromium/content/renderer/accessibility/renderer_accessibility_complete.cc b/chromium/content/renderer/accessibility/renderer_accessibility_complete.cc index abce9c8b069..7f602ff7887 100644 --- a/chromium/content/renderer/accessibility/renderer_accessibility_complete.cc +++ b/chromium/content/renderer/accessibility/renderer_accessibility_complete.cc @@ -348,7 +348,8 @@ void RendererAccessibilityComplete::SendPendingAccessibilityNotifications() { AccessibilityHostMsg_NotificationParams notification_msg; notification_msg.notification_type = notification.notification_type; notification_msg.id = notification.id; - SerializeChangedNodes(obj, ¬ification_msg.nodes); + std::set<int> ids_serialized; + SerializeChangedNodes(obj, ¬ification_msg.nodes, &ids_serialized); notification_msgs.push_back(notification_msg); #ifndef NDEBUG @@ -419,7 +420,12 @@ RendererAccessibilityComplete::CreateBrowserTreeNode() { void RendererAccessibilityComplete::SerializeChangedNodes( const WebKit::WebAccessibilityObject& obj, - std::vector<AccessibilityNodeData>* dst) { + std::vector<AccessibilityNodeData>* dst, + std::set<int>* ids_serialized) { + if (ids_serialized->find(obj.axID()) != ids_serialized->end()) + return; + ids_serialized->insert(obj.axID()); + // This method has three responsibilities: // 1. Serialize |obj| into an AccessibilityNodeData, and append it to // the end of the |dst| vector to be send to the browser process. @@ -474,6 +480,7 @@ void RendererAccessibilityComplete::SerializeChangedNodes( WebAccessibilityObject parent_obj; while (parent) { parent_obj = document.accessibilityObjectFromID(parent->id); + if (!parent_obj.isDetached()) break; parent = parent->parent; @@ -483,7 +490,7 @@ void RendererAccessibilityComplete::SerializeChangedNodes( // so that the update that clears |child| from its old parent // occurs stricly before the update that adds |child| to its // new parent. - SerializeChangedNodes(parent_obj, dst); + SerializeChangedNodes(parent_obj, dst, ids_serialized); } } } @@ -556,7 +563,7 @@ void RendererAccessibilityComplete::SerializeChangedNodes( // Serialize all of the new children, recursively. for (size_t i = 0; i < children_to_serialize.size(); ++i) - SerializeChangedNodes(children_to_serialize[i], dst); + SerializeChangedNodes(children_to_serialize[i], dst, ids_serialized); } void RendererAccessibilityComplete::ClearBrowserTreeNode( diff --git a/chromium/content/renderer/accessibility/renderer_accessibility_complete.h b/chromium/content/renderer/accessibility/renderer_accessibility_complete.h index 82fe4f81d44..4abdfb51311 100644 --- a/chromium/content/renderer/accessibility/renderer_accessibility_complete.h +++ b/chromium/content/renderer/accessibility/renderer_accessibility_complete.h @@ -5,6 +5,7 @@ #ifndef CONTENT_RENDERER_ACCESSIBILITY_RENDERER_ACCESSIBILITY_COMPLETE_H_ #define CONTENT_RENDERER_ACCESSIBILITY_RENDERER_ACCESSIBILITY_COMPLETE_H_ +#include <set> #include <vector> #include "base/containers/hash_tables.h" @@ -81,8 +82,11 @@ class CONTENT_EXPORT RendererAccessibilityComplete // Serialize the given accessibility object |obj| and append it to // |dst|, and then recursively also serialize any *new* children of // |obj|, based on what object ids we know the browser already has. + // The set of ids serialized is added to |ids_serialized|, and any + // ids previously in that set are not serialized again. void SerializeChangedNodes(const WebKit::WebAccessibilityObject& obj, - std::vector<AccessibilityNodeData>* dst); + std::vector<AccessibilityNodeData>* dst, + std::set<int>* ids_serialized); // Clear the given node and recursively delete all of its descendants // from the browser tree. (Does not delete |browser_node|). diff --git a/chromium/content/renderer/browser_plugin/browser_plugin.cc b/chromium/content/renderer/browser_plugin/browser_plugin.cc index cf0bdcc54b9..03fffc15ed5 100644 --- a/chromium/content/renderer/browser_plugin/browser_plugin.cc +++ b/chromium/content/renderer/browser_plugin/browser_plugin.cc @@ -71,7 +71,6 @@ BrowserPlugin::BrowserPlugin( WebKit::WebFrame* frame, const WebPluginParams& params) : guest_instance_id_(browser_plugin::kInstanceIDNone), - attached_(false), render_view_(render_view->AsWeakPtr()), render_view_routing_id_(render_view->GetRoutingID()), container_(NULL), @@ -86,6 +85,7 @@ BrowserPlugin::BrowserPlugin( content_window_routing_id_(MSG_ROUTING_NONE), plugin_focused_(false), visible_(true), + size_changed_in_flight_(false), before_first_navigation_(true), mouse_locked_(false), browser_plugin_manager_(render_view->GetBrowserPluginManager()), @@ -330,6 +330,21 @@ void BrowserPlugin::UpdateGuestAutoSizeState(bool current_auto_size) { resize_guest_params)); } +void BrowserPlugin::SizeChangedDueToAutoSize(const gfx::Size& old_view_size) { + size_changed_in_flight_ = false; + + std::map<std::string, base::Value*> props; + props[browser_plugin::kOldHeight] = + new base::FundamentalValue(old_view_size.height()); + props[browser_plugin::kOldWidth] = + new base::FundamentalValue(old_view_size.width()); + props[browser_plugin::kNewHeight] = + new base::FundamentalValue(last_view_size_.height()); + props[browser_plugin::kNewWidth] = + new base::FundamentalValue(last_view_size_.width()); + TriggerEvent(browser_plugin::kEventSizeChanged, &props); +} + // static bool BrowserPlugin::UsesDamageBuffer( const BrowserPluginMsg_UpdateRect_Params& params) { @@ -394,7 +409,6 @@ void BrowserPlugin::OnAttachACK( params.storage_partition_id; UpdateDOMAttribute(browser_plugin::kAttributePartition, partition_name); } - attached_ = true; } void BrowserPlugin::OnBuffersSwapped( @@ -501,9 +515,8 @@ void BrowserPlugin::OnUpdateRect( // In HW mode, we need to do it here so we can continue sending // resize messages when needed. if (params.is_resize_ack || - (!params.needs_ack && (auto_size || auto_size_ack_pending_))) { + (!params.needs_ack && (auto_size || auto_size_ack_pending_))) resize_ack_received_ = true; - } auto_size_ack_pending_ = false; @@ -546,7 +559,24 @@ void BrowserPlugin::OnUpdateRect( if (auto_size && (params.view_size != last_view_size_)) { if (backing_store_) backing_store_->Clear(SK_ColorWHITE); + gfx::Size old_view_size = last_view_size_; last_view_size_ = params.view_size; + // Schedule a SizeChanged instead of calling it directly to ensure that + // the backing store has been updated before the developer attempts to + // resize to avoid flicker. |size_changed_in_flight_| acts as a form of + // flow control for SizeChanged events. If the guest's view size is changing + // rapidly before a SizeChanged event fires, then we avoid scheduling + // another SizeChanged event. SizeChanged reads the new size from + // |last_view_size_| so we can be sure that it always fires an event + // with the last seen view size. + if (container_ && !size_changed_in_flight_) { + size_changed_in_flight_ = true; + base::MessageLoop::current()->PostTask( + FROM_HERE, + base::Bind(&BrowserPlugin::SizeChangedDueToAutoSize, + base::Unretained(this), + old_view_size)); + } } if (UsesDamageBuffer(params)) { @@ -1059,7 +1089,7 @@ void BrowserPlugin::updateGeometry( int old_width = width(); int old_height = height(); plugin_rect_ = window_rect; - if (!attached()) + if (!HasGuestInstanceID()) return; // In AutoSize mode, guests don't care when the BrowserPlugin container is diff --git a/chromium/content/renderer/browser_plugin/browser_plugin.h b/chromium/content/renderer/browser_plugin/browser_plugin.h index 89481196bec..d18906a573d 100644 --- a/chromium/content/renderer/browser_plugin/browser_plugin.h +++ b/chromium/content/renderer/browser_plugin/browser_plugin.h @@ -40,7 +40,6 @@ class CONTENT_EXPORT BrowserPlugin : RenderViewImpl* render_view() const { return render_view_.get(); } int render_view_routing_id() const { return render_view_routing_id_; } int guest_instance_id() const { return guest_instance_id_; } - bool attached() const { return attached_; } static BrowserPlugin* FromContainer(WebKit::WebPluginContainer* container); @@ -271,6 +270,9 @@ class CONTENT_EXPORT BrowserPlugin : // Informs the guest of an updated autosize state. void UpdateGuestAutoSizeState(bool current_auto_size); + // Informs the BrowserPlugin that guest has changed its size in autosize mode. + void SizeChangedDueToAutoSize(const gfx::Size& old_view_size); + // Indicates whether a damage buffer was used by the guest process for the // provided |params|. static bool UsesDamageBuffer( @@ -310,9 +312,6 @@ class CONTENT_EXPORT BrowserPlugin : // This is the browser-process-allocated instance ID that uniquely identifies // a guest WebContents. int guest_instance_id_; - // This indicates whether this BrowserPlugin has been attached to a - // WebContents. - bool attached_; base::WeakPtr<RenderViewImpl> render_view_; // We cache the |render_view_|'s routing ID because we need it on destruction. // If the |render_view_| is destroyed before the BrowserPlugin is destroyed @@ -344,6 +343,7 @@ class CONTENT_EXPORT BrowserPlugin : WebCursor cursor_; gfx::Size last_view_size_; + bool size_changed_in_flight_; bool before_first_navigation_; bool mouse_locked_; diff --git a/chromium/content/renderer/browser_plugin/browser_plugin_bindings.cc b/chromium/content/renderer/browser_plugin/browser_plugin_bindings.cc index 26f00504e32..a1025580cbe 100644 --- a/chromium/content/renderer/browser_plugin/browser_plugin_bindings.cc +++ b/chromium/content/renderer/browser_plugin/browser_plugin_bindings.cc @@ -286,6 +286,28 @@ class BrowserPluginBindingAttachWindowTo : public BrowserPluginMethodBinding { // Note: This is a method that is used internally by the <webview> shim only. // This should not be exposed to developers. +class BrowserPluginBindingGetGuestInstanceID : + public BrowserPluginMethodBinding { + public: + BrowserPluginBindingGetGuestInstanceID() + : BrowserPluginMethodBinding( + browser_plugin::kMethodGetGuestInstanceId, 0) { + } + + virtual bool Invoke(BrowserPluginBindings* bindings, + const NPVariant* args, + NPVariant* result) OVERRIDE { + int guest_instance_id = bindings->instance()->guest_instance_id(); + INT32_TO_NPVARIANT(guest_instance_id, *result); + return true; + } + + private: + DISALLOW_COPY_AND_ASSIGN(BrowserPluginBindingGetGuestInstanceID); +}; + +// Note: This is a method that is used internally by the <webview> shim only. +// This should not be exposed to developers. class BrowserPluginBindingTrackObjectLifetime : public BrowserPluginMethodBinding { public: @@ -526,6 +548,7 @@ class BrowserPluginPropertyBindingName NPVariant* result) OVERRIDE { std::string name = bindings->instance()->GetNameAttribute(); return StringToNPVariant(name, result); + return true; } virtual bool SetProperty(BrowserPluginBindings* bindings, NPObject* np_obj, @@ -566,12 +589,10 @@ class BrowserPluginPropertyBindingPartition UpdateDOMAttribute(bindings, new_value); std::string error_message; if (!bindings->instance()->ParsePartitionAttribute(&error_message)) { - // Reset to old value on error. - UpdateDOMAttribute(bindings, old_value); - // Exceptions must be set as the last operation before returning to - // script. WebBindings::setException( np_obj, static_cast<const NPUTF8 *>(error_message.c_str())); + // Reset to old value on error. + UpdateDOMAttribute(bindings, old_value); return false; } } @@ -622,12 +643,10 @@ class BrowserPluginPropertyBindingSrc : public BrowserPluginPropertyBinding { UpdateDOMAttribute(bindings, new_value); std::string error_message; if (!bindings->instance()->ParseSrcAttribute(&error_message)) { - // Reset to old value on error. - UpdateDOMAttribute(bindings, old_value); - // Exceptions must be set as the last operation before returning to - // script. WebBindings::setException( np_obj, static_cast<const NPUTF8 *>(error_message.c_str())); + // Reset to old value on error. + UpdateDOMAttribute(bindings, old_value); return false; } } @@ -636,8 +655,6 @@ class BrowserPluginPropertyBindingSrc : public BrowserPluginPropertyBinding { virtual void RemoveProperty(BrowserPluginBindings* bindings, NPObject* np_obj) OVERRIDE { std::string old_value = bindings->instance()->GetSrcAttribute(); - if (old_value.empty()) - return; // Remove the DOM attribute to trigger the mutation observer when it is // restored to its original value again. bindings->instance()->RemoveDOMAttribute(name()); @@ -668,6 +685,7 @@ BrowserPluginBindings::BrowserPluginBindings(BrowserPlugin* instance) method_bindings_.push_back(new BrowserPluginBindingAttach); method_bindings_.push_back(new BrowserPluginBindingAttachWindowTo); + method_bindings_.push_back(new BrowserPluginBindingGetGuestInstanceID); method_bindings_.push_back(new BrowserPluginBindingTrackObjectLifetime); property_bindings_.push_back(new BrowserPluginPropertyBindingAutoSize); diff --git a/chromium/content/renderer/browser_plugin/browser_plugin_browsertest.cc b/chromium/content/renderer/browser_plugin/browser_plugin_browsertest.cc index 693752c618a..1ad07e9845b 100644 --- a/chromium/content/renderer/browser_plugin/browser_plugin_browsertest.cc +++ b/chromium/content/renderer/browser_plugin/browser_plugin_browsertest.cc @@ -172,13 +172,8 @@ MockBrowserPlugin* BrowserPluginTest::GetCurrentPluginWithAttachParams( msg, &iter, params)) return NULL; - MockBrowserPlugin* browser_plugin = static_cast<MockBrowserPlugin*>( + return static_cast<MockBrowserPlugin*>( browser_plugin_manager()->GetBrowserPlugin(instance_id)); - - BrowserPluginMsg_Attach_ACK_Params attach_ack_params; - browser_plugin->OnAttachACK(instance_id, attach_ack_params); - - return browser_plugin; } // This test verifies that an initial resize occurs when we instantiate the diff --git a/chromium/content/renderer/browser_plugin/mock_browser_plugin.h b/chromium/content/renderer/browser_plugin/mock_browser_plugin.h index acd001b64ca..ac12aa3015e 100644 --- a/chromium/content/renderer/browser_plugin/mock_browser_plugin.h +++ b/chromium/content/renderer/browser_plugin/mock_browser_plugin.h @@ -18,7 +18,6 @@ class MockBrowserPlugin : public BrowserPlugin { virtual ~MockBrowserPlugin(); // Allow poking at a few private members. - using BrowserPlugin::OnAttachACK; using BrowserPlugin::guest_crashed_; using BrowserPlugin::pending_damage_buffer_; using BrowserPlugin::damage_buffer_sequence_id_; diff --git a/chromium/content/renderer/gpu/gpu_benchmarking_extension.cc b/chromium/content/renderer/gpu/gpu_benchmarking_extension.cc index 65b451159f0..a274d0d8361 100644 --- a/chromium/content/renderer/gpu/gpu_benchmarking_extension.cc +++ b/chromium/content/renderer/gpu/gpu_benchmarking_extension.cc @@ -16,6 +16,7 @@ #include "content/public/renderer/render_thread.h" #include "content/renderer/gpu/render_widget_compositor.h" #include "content/renderer/render_view_impl.h" +#include "content/renderer/rendering_benchmark.h" #include "content/renderer/skia_benchmarking_extension.h" #include "third_party/WebKit/public/web/WebFrame.h" #include "third_party/WebKit/public/web/WebImageCache.h" diff --git a/chromium/content/renderer/media/android/media_source_delegate.cc b/chromium/content/renderer/media/android/media_source_delegate.cc index 715d5207c4a..c13a4987fb7 100644 --- a/chromium/content/renderer/media/android/media_source_delegate.cc +++ b/chromium/content/renderer/media/android/media_source_delegate.cc @@ -37,6 +37,22 @@ const uint8 kVorbisPadding[] = { 0xff, 0xff, 0xff, 0xff }; namespace content { +#define BIND_TO_RENDER_LOOP(function) \ + media::BindToLoop(main_loop_, \ + base::Bind(function, main_weak_this_.GetWeakPtr())) + +#define BIND_TO_RENDER_LOOP_1(function, arg1) \ + media::BindToLoop(main_loop_, \ + base::Bind(function, main_weak_this_.GetWeakPtr(), arg1)) + +#if defined(GOOGLE_TV) +#define DCHECK_BELONG_TO_MEDIA_LOOP() \ + DCHECK(media_loop_->BelongsToCurrentThread()) +#else +#define DCHECK_BELONG_TO_MEDIA_LOOP() \ + DCHECK(main_loop_->BelongsToCurrentThread()) +#endif + static void LogMediaSourceError(const scoped_refptr<media::MediaLog>& media_log, const std::string& error) { media_log->AddEvent(media_log->CreateMediaSourceErrorEvent(error)); @@ -50,16 +66,15 @@ MediaSourceDelegate::MediaSourceDelegate( : main_weak_this_(this), media_weak_this_(this), main_loop_(base::MessageLoopProxy::current()), +#if defined(GOOGLE_TV) media_loop_(media_loop), - send_read_from_demuxer_ack_cb_(media::BindToLoop(main_loop_, - base::Bind(&MediaSourceDelegate::SendReadFromDemuxerAck, - main_weak_this_.GetWeakPtr()))), - send_seek_request_ack_cb_(media::BindToLoop(main_loop_, - base::Bind(&MediaSourceDelegate::SendSeekRequestAck, - main_weak_this_.GetWeakPtr()))), - send_demuxer_ready_cb_(media::BindToLoop(main_loop_, - base::Bind(&MediaSourceDelegate::SendDemuxerReady, - main_weak_this_.GetWeakPtr()))), + send_read_from_demuxer_ack_cb_( + BIND_TO_RENDER_LOOP(&MediaSourceDelegate::SendReadFromDemuxerAck)), + send_seek_request_ack_cb_( + BIND_TO_RENDER_LOOP(&MediaSourceDelegate::SendSeekRequestAck)), + send_demuxer_ready_cb_( + BIND_TO_RENDER_LOOP(&MediaSourceDelegate::SendDemuxerReady)), +#endif proxy_(proxy), player_id_(player_id), media_log_(media_log), @@ -102,16 +117,20 @@ void MediaSourceDelegate::Destroy() { if (chunk_demuxer_) chunk_demuxer_->Shutdown(); +#if defined(GOOGLE_TV) // |this| will be transfered to the callback StopDemuxer() and // OnDemuxerStopDone(). they own |this| and OnDemuxerStopDone() will delete // it when called. Hence using base::Unretained(this) is safe here. media_loop_->PostTask(FROM_HERE, base::Bind(&MediaSourceDelegate::StopDemuxer, base::Unretained(this))); +#else + StopDemuxer(); +#endif } void MediaSourceDelegate::StopDemuxer() { - DCHECK(media_loop_->BelongsToCurrentThread()); + DCHECK_BELONG_TO_MEDIA_LOOP(); DCHECK(demuxer_); audio_stream_ = NULL; @@ -147,26 +166,26 @@ void MediaSourceDelegate::InitializeMediaSource( access_unit_size_ = kAccessUnitSizeForMediaSource; chunk_demuxer_.reset(new media::ChunkDemuxer( - media::BindToLoop(main_loop_, - base::Bind(&MediaSourceDelegate::OnDemuxerOpened, - main_weak_this_.GetWeakPtr())), - media::BindToLoop(main_loop_, - base::Bind(&MediaSourceDelegate::OnNeedKey, - main_weak_this_.GetWeakPtr(), "")), + BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnDemuxerOpened), + BIND_TO_RENDER_LOOP_1(&MediaSourceDelegate::OnNeedKey, ""), // WeakPtrs can only bind to methods without return values. base::Bind(&MediaSourceDelegate::OnAddTextTrack, base::Unretained(this)), base::Bind(&LogMediaSourceError, media_log_))); demuxer_ = chunk_demuxer_.get(); +#if defined(GOOGLE_TV) // |this| will be retained until StopDemuxer() is posted, so Unretained() is // safe here. media_loop_->PostTask(FROM_HERE, base::Bind(&MediaSourceDelegate::InitializeDemuxer, base::Unretained(this))); +#else + InitializeDemuxer(); +#endif } void MediaSourceDelegate::InitializeDemuxer() { - DCHECK(media_loop_->BelongsToCurrentThread()); + DCHECK_BELONG_TO_MEDIA_LOOP(); demuxer_->Initialize(this, base::Bind(&MediaSourceDelegate::OnDemuxerInitDone, media_weak_this_.GetWeakPtr())); } @@ -230,15 +249,19 @@ void MediaSourceDelegate::Seek(base::TimeDelta time, unsigned seek_request_id) { } SetSeeking(true); +#if defined(GOOGLE_TV) media_loop_->PostTask(FROM_HERE, base::Bind(&MediaSourceDelegate::SeekInternal, base::Unretained(this), time, seek_request_id)); +#else + SeekInternal(time, seek_request_id); +#endif } void MediaSourceDelegate::SeekInternal(base::TimeDelta time, unsigned request_id) { - DCHECK(media_loop_->BelongsToCurrentThread()); + DCHECK_BELONG_TO_MEDIA_LOOP(); demuxer_->Seek(time, base::Bind(&MediaSourceDelegate::OnDemuxerSeekDone, media_weak_this_.GetWeakPtr(), request_id)); } @@ -266,15 +289,19 @@ void MediaSourceDelegate::SetDuration(base::TimeDelta duration) { void MediaSourceDelegate::OnReadFromDemuxer(media::DemuxerStream::Type type) { DCHECK(main_loop_->BelongsToCurrentThread()); +#if defined(GOOGLE_TV) media_loop_->PostTask( FROM_HERE, base::Bind(&MediaSourceDelegate::OnReadFromDemuxerInternal, base::Unretained(this), type)); +#else + OnReadFromDemuxerInternal(type); +#endif } void MediaSourceDelegate::OnReadFromDemuxerInternal( media::DemuxerStream::Type type) { - DCHECK(media_loop_->BelongsToCurrentThread()); + DCHECK_BELONG_TO_MEDIA_LOOP(); DVLOG(1) << "OnReadFromDemuxer(" << type << ") : " << player_id_; if (IsSeeking()) return; // Drop the request during seeking. @@ -293,8 +320,7 @@ void MediaSourceDelegate::ReadFromDemuxerStream( media::DemuxerStream::Type type, scoped_ptr<MediaPlayerHostMsg_ReadFromDemuxerAck_Params> params, size_t index) { - DCHECK(media_loop_->BelongsToCurrentThread()); - DCHECK(!IsSeeking()); + DCHECK_BELONG_TO_MEDIA_LOOP(); // DemuxerStream::Read() always returns the read callback asynchronously. DemuxerStream* stream = (type == DemuxerStream::AUDIO) ? audio_stream_ : video_stream_; @@ -309,7 +335,7 @@ void MediaSourceDelegate::OnBufferReady( size_t index, DemuxerStream::Status status, const scoped_refptr<media::DecoderBuffer>& buffer) { - DCHECK(media_loop_->BelongsToCurrentThread()); + DCHECK_BELONG_TO_MEDIA_LOOP(); DVLOG(1) << "OnBufferReady(" << index << ", " << status << ", " << ((!buffer || buffer->end_of_stream()) ? -1 : buffer->timestamp().InMilliseconds()) @@ -406,7 +432,11 @@ void MediaSourceDelegate::OnBufferReady( NOTREACHED(); } +#if defined(GOOGLE_TV) send_read_from_demuxer_ack_cb_.Run(params.Pass()); +#else + SendReadFromDemuxerAck(params.Pass()); +#endif } void MediaSourceDelegate::SendReadFromDemuxerAck( @@ -424,7 +454,7 @@ void MediaSourceDelegate::OnDemuxerError(media::PipelineStatus status) { } void MediaSourceDelegate::OnDemuxerInitDone(media::PipelineStatus status) { - DCHECK(media_loop_->BelongsToCurrentThread()); + DCHECK_BELONG_TO_MEDIA_LOOP(); DVLOG(1) << "OnDemuxerInitDone(" << status << ") : " << player_id_; DCHECK(demuxer_); @@ -457,7 +487,7 @@ void MediaSourceDelegate::OnDemuxerInitDone(media::PipelineStatus status) { } void MediaSourceDelegate::InitAudioDecryptingDemuxerStream() { - DCHECK(media_loop_->BelongsToCurrentThread()); + DCHECK_BELONG_TO_MEDIA_LOOP(); DVLOG(1) << "InitAudioDecryptingDemuxerStream() : " << player_id_; DCHECK(!set_decryptor_ready_cb_.is_null()); @@ -470,7 +500,7 @@ void MediaSourceDelegate::InitAudioDecryptingDemuxerStream() { } void MediaSourceDelegate::InitVideoDecryptingDemuxerStream() { - DCHECK(media_loop_->BelongsToCurrentThread()); + DCHECK_BELONG_TO_MEDIA_LOOP(); DVLOG(1) << "InitVideoDecryptingDemuxerStream() : " << player_id_; DCHECK(!set_decryptor_ready_cb_.is_null()); @@ -484,7 +514,7 @@ void MediaSourceDelegate::InitVideoDecryptingDemuxerStream() { void MediaSourceDelegate::OnAudioDecryptingDemuxerStreamInitDone( media::PipelineStatus status) { - DCHECK(media_loop_->BelongsToCurrentThread()); + DCHECK_BELONG_TO_MEDIA_LOOP(); DVLOG(1) << "OnAudioDecryptingDemuxerStreamInitDone(" << status << ") : " << player_id_; DCHECK(demuxer_); @@ -508,7 +538,7 @@ void MediaSourceDelegate::OnAudioDecryptingDemuxerStreamInitDone( void MediaSourceDelegate::OnVideoDecryptingDemuxerStreamInitDone( media::PipelineStatus status) { - DCHECK(media_loop_->BelongsToCurrentThread()); + DCHECK_BELONG_TO_MEDIA_LOOP(); DVLOG(1) << "OnVideoDecryptingDemuxerStreamInitDone(" << status << ") : " << player_id_; DCHECK(demuxer_); @@ -526,7 +556,7 @@ void MediaSourceDelegate::OnVideoDecryptingDemuxerStreamInitDone( void MediaSourceDelegate::OnDemuxerSeekDone(unsigned seek_request_id, media::PipelineStatus status) { - DCHECK(media_loop_->BelongsToCurrentThread()); + DCHECK_BELONG_TO_MEDIA_LOOP(); DVLOG(1) << "OnDemuxerSeekDone(" << status << ") : " << player_id_; DCHECK(IsSeeking()); @@ -547,7 +577,7 @@ void MediaSourceDelegate::OnDemuxerSeekDone(unsigned seek_request_id, } void MediaSourceDelegate::ResetAudioDecryptingDemuxerStream() { - DCHECK(media_loop_->BelongsToCurrentThread()); + DCHECK_BELONG_TO_MEDIA_LOOP(); DVLOG(1) << "ResetAudioDecryptingDemuxerStream() : " << player_id_; if (audio_decrypting_demuxer_stream_) { audio_decrypting_demuxer_stream_->Reset( @@ -559,12 +589,22 @@ void MediaSourceDelegate::ResetAudioDecryptingDemuxerStream() { } void MediaSourceDelegate::ResetVideoDecryptingDemuxerStream() { - DCHECK(media_loop_->BelongsToCurrentThread()); + DCHECK_BELONG_TO_MEDIA_LOOP(); DVLOG(1) << "ResetVideoDecryptingDemuxerStream()"; +#if defined(GOOGLE_TV) if (video_decrypting_demuxer_stream_) video_decrypting_demuxer_stream_->Reset(send_seek_request_ack_cb_); else send_seek_request_ack_cb_.Run(); +#else + if (video_decrypting_demuxer_stream_) { + video_decrypting_demuxer_stream_->Reset( + base::Bind(&MediaSourceDelegate::SendSeekRequestAck, + main_weak_this_.GetWeakPtr())); + } else { + SendSeekRequestAck(); + } +#endif } void MediaSourceDelegate::SendSeekRequestAck() { @@ -583,23 +623,27 @@ void MediaSourceDelegate::OnDemuxerStopDone() { } void MediaSourceDelegate::OnMediaConfigRequest() { +#if defined(GOOGLE_TV) if (!media_loop_->BelongsToCurrentThread()) { media_loop_->PostTask(FROM_HERE, base::Bind(&MediaSourceDelegate::OnMediaConfigRequest, base::Unretained(this))); return; } +#endif if (CanNotifyDemuxerReady()) NotifyDemuxerReady(); } void MediaSourceDelegate::NotifyKeyAdded(const std::string& key_system) { +#if defined(GOOGLE_TV) if (!media_loop_->BelongsToCurrentThread()) { media_loop_->PostTask(FROM_HERE, base::Bind(&MediaSourceDelegate::NotifyKeyAdded, base::Unretained(this), key_system)); return; } +#endif DVLOG(1) << "NotifyKeyAdded() : " << player_id_; // TODO(kjyoun): Enhance logic to detect when to call NotifyDemuxerReady() // For now, we calls it when the first key is added. See @@ -615,7 +659,7 @@ void MediaSourceDelegate::NotifyKeyAdded(const std::string& key_system) { } bool MediaSourceDelegate::CanNotifyDemuxerReady() { - DCHECK(media_loop_->BelongsToCurrentThread()); + DCHECK_BELONG_TO_MEDIA_LOOP(); // This can happen when a key is added before the demuxer is initialized. // See NotifyKeyAdded(). // TODO(kjyoun): Remove NotifyDemxuerReady() call from NotifyKeyAdded() so @@ -629,7 +673,7 @@ bool MediaSourceDelegate::CanNotifyDemuxerReady() { } void MediaSourceDelegate::NotifyDemuxerReady() { - DCHECK(media_loop_->BelongsToCurrentThread()); + DCHECK_BELONG_TO_MEDIA_LOOP(); DVLOG(1) << "NotifyDemuxerReady() : " << player_id_; DCHECK(CanNotifyDemuxerReady()); @@ -656,7 +700,11 @@ void MediaSourceDelegate::NotifyDemuxerReady() { params->duration_ms = GetDurationMs(); params->key_system = HasEncryptedStream() ? key_system_ : ""; +#if defined(GOOGLE_TV) send_demuxer_ready_cb_.Run(params.Pass()); +#else + SendDemuxerReady(params.Pass()); +#endif } void MediaSourceDelegate::SendDemuxerReady( @@ -667,7 +715,7 @@ void MediaSourceDelegate::SendDemuxerReady( } int MediaSourceDelegate::GetDurationMs() { - DCHECK(media_loop_->BelongsToCurrentThread()); + DCHECK_BELONG_TO_MEDIA_LOOP(); if (!chunk_demuxer_) return -1; @@ -708,7 +756,7 @@ scoped_ptr<media::TextTrack> MediaSourceDelegate::OnAddTextTrack( } bool MediaSourceDelegate::HasEncryptedStream() { - DCHECK(media_loop_->BelongsToCurrentThread()); + DCHECK_BELONG_TO_MEDIA_LOOP(); return (audio_stream_ && audio_stream_->audio_decoder_config().is_encrypted()) || (video_stream_ && diff --git a/chromium/content/renderer/media/android/media_source_delegate.h b/chromium/content/renderer/media/android/media_source_delegate.h index 8f359814e55..1c358d51d85 100644 --- a/chromium/content/renderer/media/android/media_source_delegate.h +++ b/chromium/content/renderer/media/android/media_source_delegate.h @@ -184,6 +184,7 @@ class MediaSourceDelegate : public media::DemuxerHost { // Message loop for main renderer thread. const scoped_refptr<base::MessageLoopProxy> main_loop_; +#if defined(GOOGLE_TV) // Message loop for the media thread. // When there is high load in the render thread, the reading from |demuxer_| // and its read-callback loops run very slowly. To improve the response time @@ -193,6 +194,7 @@ class MediaSourceDelegate : public media::DemuxerHost { ReadFromDemuxerAckCB send_read_from_demuxer_ack_cb_; base::Closure send_seek_request_ack_cb_; DemuxerReadyCB send_demuxer_ready_cb_; +#endif WebMediaPlayerProxyAndroid* proxy_; int player_id_; diff --git a/chromium/content/renderer/media/media_stream_dependency_factory.cc b/chromium/content/renderer/media/media_stream_dependency_factory.cc index b5adf1ed754..2d19ae035f2 100644 --- a/chromium/content/renderer/media/media_stream_dependency_factory.cc +++ b/chromium/content/renderer/media/media_stream_dependency_factory.cc @@ -16,7 +16,6 @@ #include "content/renderer/media/rtc_peer_connection_handler.h" #include "content/renderer/media/rtc_video_capturer.h" #include "content/renderer/media/rtc_video_decoder_factory.h" -#include "content/renderer/media/rtc_video_encoder_factory.h" #include "content/renderer/media/video_capture_impl_manager.h" #include "content/renderer/media/webaudio_capturer_source.h" #include "content/renderer/media/webrtc_audio_device_impl.h" @@ -28,7 +27,7 @@ #include "content/renderer/p2p/port_allocator.h" #include "content/renderer/render_thread_impl.h" #include "jingle/glue/thread_wrapper.h" -#include "media/filters/gpu_video_accelerator_factories.h" +#include "media/filters/gpu_video_decoder_factories.h" #include "third_party/WebKit/public/platform/WebMediaConstraints.h" #include "third_party/WebKit/public/platform/WebMediaStream.h" #include "third_party/WebKit/public/platform/WebMediaStreamSource.h" @@ -489,32 +488,27 @@ bool MediaStreamDependencyFactory::CreatePeerConnectionFactory() { audio_device_ = new WebRtcAudioDeviceImpl(); scoped_ptr<cricket::WebRtcVideoDecoderFactory> decoder_factory; - scoped_ptr<cricket::WebRtcVideoEncoderFactory> encoder_factory; const CommandLine* cmd_line = CommandLine::ForCurrentProcess(); - scoped_refptr<base::MessageLoopProxy> media_loop_proxy = - RenderThreadImpl::current()->GetMediaThreadMessageLoopProxy(); - scoped_refptr<RendererGpuVideoAcceleratorFactories> gpu_factories = - RenderThreadImpl::current()->GetGpuFactories(media_loop_proxy); -#if !defined(GOOGLE_TV) - if (cmd_line->HasSwitch(switches::kEnableWebRtcHWDecoding)) - if (gpu_factories) + if (cmd_line->HasSwitch(switches::kEnableWebRtcHWDecoding)) { + scoped_refptr<base::MessageLoopProxy> media_loop_proxy = + RenderThreadImpl::current()->GetMediaThreadMessageLoopProxy(); + scoped_refptr<RendererGpuVideoDecoderFactories> gpu_factories = + RenderThreadImpl::current()->GetGpuFactories(media_loop_proxy); + if (gpu_factories.get() != NULL) decoder_factory.reset(new RTCVideoDecoderFactory(gpu_factories)); -#else + } +#if defined(GOOGLE_TV) // PeerConnectionFactory will hold the ownership of this // VideoDecoderFactory. - decoder_factory.reset(decoder_factory_tv_ = new RTCVideoDecoderFactoryTv()); + decoder_factory.reset(decoder_factory_tv_ = new RTCVideoDecoderFactoryTv); #endif - if (cmd_line->HasSwitch(switches::kEnableWebRtcHWEncoding)) - if (gpu_factories) - encoder_factory.reset(new RTCVideoEncoderFactory(gpu_factories)); - scoped_refptr<webrtc::PeerConnectionFactoryInterface> factory( webrtc::CreatePeerConnectionFactory(worker_thread_, signaling_thread_, audio_device_.get(), - encoder_factory.release(), + NULL, decoder_factory.release())); if (factory.get()) pc_factory_ = factory; diff --git a/chromium/content/renderer/media/media_stream_impl.cc b/chromium/content/renderer/media/media_stream_impl.cc index 6ce995e2608..5edc4cc5f16 100644 --- a/chromium/content/renderer/media/media_stream_impl.cc +++ b/chromium/content/renderer/media/media_stream_impl.cc @@ -75,11 +75,6 @@ void UpdateRequestOptions( options->video_type = content::MEDIA_DESKTOP_VIDEO_CAPTURE; options->video_device_id = DesktopMediaID(DesktopMediaID::TYPE_SCREEN, 0).ToString(); - } else if (video_stream_source == kMediaStreamSourceDesktop) { - options->video_type = content::MEDIA_DESKTOP_VIDEO_CAPTURE; - options->video_device_id = GetStreamConstraint( - user_media_request.videoConstraints(), - kMediaStreamSourceId, true); } } } diff --git a/chromium/content/renderer/media/peer_connection_tracker.cc b/chromium/content/renderer/media/peer_connection_tracker.cc index 597c6455704..44f44458aac 100644 --- a/chromium/content/renderer/media/peer_connection_tracker.cc +++ b/chromium/content/renderer/media/peer_connection_tracker.cc @@ -161,9 +161,15 @@ static base::DictionaryValue* GetDictValueStats( return NULL; DictionaryValue* dict = new base::DictionaryValue(); + if (!dict) + return NULL; dict->SetDouble("timestamp", report.timestamp); base::ListValue* values = new base::ListValue(); + if (!values) { + delete dict; + return NULL; + } dict->Set("values", values); for (size_t i = 0; i < report.values.size(); ++i) { @@ -183,10 +189,14 @@ static base::DictionaryValue* GetDictValue(const webrtc::StatsReport& report) { return NULL; result.reset(new base::DictionaryValue()); + if (!result) + return NULL; + // Note: // The format must be consistent with what webrtc_internals.js expects. // If you change it here, you must change webrtc_internals.js as well. - result->Set("stats", stats.release()); + if (stats) + result->Set("stats", stats.release()); result->SetString("id", report.id); result->SetString("type", report.type); diff --git a/chromium/content/renderer/media/renderer_gpu_video_accelerator_factories.cc b/chromium/content/renderer/media/renderer_gpu_video_decoder_factories.cc index f586497f484..d33e5901b2a 100644 --- a/chromium/content/renderer/media/renderer_gpu_video_accelerator_factories.cc +++ b/chromium/content/renderer/media/renderer_gpu_video_decoder_factories.cc @@ -1,8 +1,8 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. +// 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/renderer/media/renderer_gpu_video_accelerator_factories.h" +#include "content/renderer/media/renderer_gpu_video_decoder_factories.h" #include <GLES2/gl2.h> #include <GLES2/gl2ext.h> @@ -17,8 +17,8 @@ namespace content { -RendererGpuVideoAcceleratorFactories::~RendererGpuVideoAcceleratorFactories() {} -RendererGpuVideoAcceleratorFactories::RendererGpuVideoAcceleratorFactories( +RendererGpuVideoDecoderFactories::~RendererGpuVideoDecoderFactories() {} +RendererGpuVideoDecoderFactories::RendererGpuVideoDecoderFactories( GpuChannelHost* gpu_channel_host, const scoped_refptr<base::MessageLoopProxy>& message_loop, WebGraphicsContext3DCommandBufferImpl* context) @@ -28,37 +28,32 @@ RendererGpuVideoAcceleratorFactories::RendererGpuVideoAcceleratorFactories( aborted_waiter_(true, false), message_loop_async_waiter_(false, false), render_thread_async_waiter_(false, false) { - // |context| is only required to support HW-accelerated decode. - if (!context) - return; - if (message_loop_->BelongsToCurrentThread()) { AsyncGetContext(context); message_loop_async_waiter_.Reset(); return; } // Wait for the context to be acquired. - message_loop_->PostTask( - FROM_HERE, - base::Bind(&RendererGpuVideoAcceleratorFactories::AsyncGetContext, - // Unretained to avoid ref/deref'ing |*this|, which is not yet - // stored in a scoped_refptr. Safe because the Wait() below - // keeps us alive until this task completes. - base::Unretained(this), - // OK to pass raw because the pointee is only deleted on the - // compositor thread, and only as the result of a PostTask from - // the render thread which can only happen after this function - // returns, so our PostTask will run first. - context)); + message_loop_->PostTask(FROM_HERE, base::Bind( + &RendererGpuVideoDecoderFactories::AsyncGetContext, + // Unretained to avoid ref/deref'ing |*this|, which is not yet stored in a + // scoped_refptr. Safe because the Wait() below keeps us alive until this + // task completes. + base::Unretained(this), + // OK to pass raw because the pointee is only deleted on the compositor + // thread, and only as the result of a PostTask from the render thread + // which can only happen after this function returns, so our PostTask will + // run first. + context)); message_loop_async_waiter_.Wait(); } -RendererGpuVideoAcceleratorFactories::RendererGpuVideoAcceleratorFactories() +RendererGpuVideoDecoderFactories::RendererGpuVideoDecoderFactories() : aborted_waiter_(true, false), message_loop_async_waiter_(false, false), render_thread_async_waiter_(false, false) {} -void RendererGpuVideoAcceleratorFactories::AsyncGetContext( +void RendererGpuVideoDecoderFactories::AsyncGetContext( WebGraphicsContext3DCommandBufferImpl* context) { context_ = context->AsWeakPtr(); if (context_.get()) { @@ -71,23 +66,20 @@ void RendererGpuVideoAcceleratorFactories::AsyncGetContext( message_loop_async_waiter_.Signal(); } -scoped_ptr<media::VideoDecodeAccelerator> -RendererGpuVideoAcceleratorFactories::CreateVideoDecodeAccelerator( +media::VideoDecodeAccelerator* +RendererGpuVideoDecoderFactories::CreateVideoDecodeAccelerator( media::VideoCodecProfile profile, media::VideoDecodeAccelerator::Client* client) { if (message_loop_->BelongsToCurrentThread()) { AsyncCreateVideoDecodeAccelerator(profile, client); message_loop_async_waiter_.Reset(); - return vda_.Pass(); + return vda_.release(); } // The VDA is returned in the vda_ member variable by the // AsyncCreateVideoDecodeAccelerator() function. - message_loop_->PostTask(FROM_HERE, - base::Bind(&RendererGpuVideoAcceleratorFactories:: - AsyncCreateVideoDecodeAccelerator, - this, - profile, - client)); + message_loop_->PostTask(FROM_HERE, base::Bind( + &RendererGpuVideoDecoderFactories::AsyncCreateVideoDecodeAccelerator, + this, profile, client)); base::WaitableEvent* objects[] = {&aborted_waiter_, &message_loop_async_waiter_}; @@ -95,49 +87,17 @@ RendererGpuVideoAcceleratorFactories::CreateVideoDecodeAccelerator( // If we are aborting and the VDA is created by the // AsyncCreateVideoDecodeAccelerator() function later we need to ensure // that it is destroyed on the same thread. - message_loop_->PostTask(FROM_HERE, - base::Bind(&RendererGpuVideoAcceleratorFactories:: - AsyncDestroyVideoDecodeAccelerator, - this)); - return scoped_ptr<media::VideoDecodeAccelerator>(); - } - return vda_.Pass(); -} - -scoped_ptr<media::VideoEncodeAccelerator> -RendererGpuVideoAcceleratorFactories::CreateVideoEncodeAccelerator( - media::VideoEncodeAccelerator::Client* client) { - if (message_loop_->BelongsToCurrentThread()) { - AsyncCreateVideoEncodeAccelerator(client); - message_loop_async_waiter_.Reset(); - return vea_.Pass(); - } - // The VEA is returned in the vea_ member variable by the - // AsyncCreateVideoEncodeAccelerator() function. - message_loop_->PostTask(FROM_HERE, - base::Bind(&RendererGpuVideoAcceleratorFactories:: - AsyncCreateVideoEncodeAccelerator, - this, - client)); - - base::WaitableEvent* objects[] = {&aborted_waiter_, - &message_loop_async_waiter_}; - if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0) { - // If we are aborting and the VDA is created by the - // AsyncCreateVideoEncodeAccelerator() function later we need to ensure - // that it is destroyed on the same thread. - message_loop_->PostTask(FROM_HERE, - base::Bind(&RendererGpuVideoAcceleratorFactories:: - AsyncDestroyVideoEncodeAccelerator, - this)); - return scoped_ptr<media::VideoEncodeAccelerator>(); + message_loop_->PostTask(FROM_HERE, base::Bind( + &RendererGpuVideoDecoderFactories::AsyncDestroyVideoDecodeAccelerator, + this)); + return NULL; } - return vea_.Pass(); + return vda_.release(); } -void RendererGpuVideoAcceleratorFactories::AsyncCreateVideoDecodeAccelerator( - media::VideoCodecProfile profile, - media::VideoDecodeAccelerator::Client* client) { +void RendererGpuVideoDecoderFactories::AsyncCreateVideoDecodeAccelerator( + media::VideoCodecProfile profile, + media::VideoDecodeAccelerator::Client* client) { DCHECK(message_loop_->BelongsToCurrentThread()); if (context_.get() && context_->GetCommandBufferProxy()) { @@ -147,17 +107,8 @@ void RendererGpuVideoAcceleratorFactories::AsyncCreateVideoDecodeAccelerator( message_loop_async_waiter_.Signal(); } -void RendererGpuVideoAcceleratorFactories::AsyncCreateVideoEncodeAccelerator( - media::VideoEncodeAccelerator::Client* client) { - DCHECK(message_loop_->BelongsToCurrentThread()); - - vea_ = gpu_channel_host_->CreateVideoEncoder(client).Pass(); - message_loop_async_waiter_.Signal(); -} - -uint32 RendererGpuVideoAcceleratorFactories::CreateTextures( - int32 count, - const gfx::Size& size, +uint32 RendererGpuVideoDecoderFactories::CreateTextures( + int32 count, const gfx::Size& size, std::vector<uint32>* texture_ids, std::vector<gpu::Mailbox>* texture_mailboxes, uint32 texture_target) { @@ -170,14 +121,9 @@ uint32 RendererGpuVideoAcceleratorFactories::CreateTextures( message_loop_async_waiter_.Reset(); return sync_point; } - message_loop_->PostTask( - FROM_HERE, - base::Bind(&RendererGpuVideoAcceleratorFactories::AsyncCreateTextures, - this, - count, - size, - texture_target, - &sync_point)); + message_loop_->PostTask(FROM_HERE, base::Bind( + &RendererGpuVideoDecoderFactories::AsyncCreateTextures, this, + count, size, texture_target, &sync_point)); base::WaitableEvent* objects[] = {&aborted_waiter_, &message_loop_async_waiter_}; @@ -188,10 +134,8 @@ uint32 RendererGpuVideoAcceleratorFactories::CreateTextures( return sync_point; } -void RendererGpuVideoAcceleratorFactories::AsyncCreateTextures( - int32 count, - const gfx::Size& size, - uint32 texture_target, +void RendererGpuVideoDecoderFactories::AsyncCreateTextures( + int32 count, const gfx::Size& size, uint32 texture_target, uint32* sync_point) { DCHECK(message_loop_->BelongsToCurrentThread()); DCHECK(texture_target); @@ -213,15 +157,8 @@ void RendererGpuVideoAcceleratorFactories::AsyncCreateTextures( gles2->TexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); gles2->TexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); if (texture_target == GL_TEXTURE_2D) { - gles2->TexImage2D(texture_target, - 0, - GL_RGBA, - size.width(), - size.height(), - 0, - GL_RGBA, - GL_UNSIGNED_BYTE, - NULL); + gles2->TexImage2D(texture_target, 0, GL_RGBA, size.width(), size.height(), + 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); } gles2->GenMailboxCHROMIUM(created_texture_mailboxes_[i].name); gles2->ProduceTextureCHROMIUM(texture_target, @@ -238,20 +175,16 @@ void RendererGpuVideoAcceleratorFactories::AsyncCreateTextures( message_loop_async_waiter_.Signal(); } -void RendererGpuVideoAcceleratorFactories::DeleteTexture(uint32 texture_id) { +void RendererGpuVideoDecoderFactories::DeleteTexture(uint32 texture_id) { if (message_loop_->BelongsToCurrentThread()) { AsyncDeleteTexture(texture_id); return; } - message_loop_->PostTask( - FROM_HERE, - base::Bind(&RendererGpuVideoAcceleratorFactories::AsyncDeleteTexture, - this, - texture_id)); + message_loop_->PostTask(FROM_HERE, base::Bind( + &RendererGpuVideoDecoderFactories::AsyncDeleteTexture, this, texture_id)); } -void RendererGpuVideoAcceleratorFactories::AsyncDeleteTexture( - uint32 texture_id) { +void RendererGpuVideoDecoderFactories::AsyncDeleteTexture(uint32 texture_id) { DCHECK(message_loop_->BelongsToCurrentThread()); if (!context_.get()) return; @@ -261,25 +194,23 @@ void RendererGpuVideoAcceleratorFactories::AsyncDeleteTexture( DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR)); } -void RendererGpuVideoAcceleratorFactories::WaitSyncPoint(uint32 sync_point) { +void RendererGpuVideoDecoderFactories::WaitSyncPoint(uint32 sync_point) { if (message_loop_->BelongsToCurrentThread()) { AsyncWaitSyncPoint(sync_point); message_loop_async_waiter_.Reset(); return; } - message_loop_->PostTask( - FROM_HERE, - base::Bind(&RendererGpuVideoAcceleratorFactories::AsyncWaitSyncPoint, - this, - sync_point)); + message_loop_->PostTask(FROM_HERE, base::Bind( + &RendererGpuVideoDecoderFactories::AsyncWaitSyncPoint, + this, + sync_point)); base::WaitableEvent* objects[] = {&aborted_waiter_, &message_loop_async_waiter_}; base::WaitableEvent::WaitMany(objects, arraysize(objects)); } -void RendererGpuVideoAcceleratorFactories::AsyncWaitSyncPoint( - uint32 sync_point) { +void RendererGpuVideoDecoderFactories::AsyncWaitSyncPoint(uint32 sync_point) { DCHECK(message_loop_->BelongsToCurrentThread()); if (!context_) { message_loop_async_waiter_.Signal(); @@ -291,10 +222,9 @@ void RendererGpuVideoAcceleratorFactories::AsyncWaitSyncPoint( message_loop_async_waiter_.Signal(); } -void RendererGpuVideoAcceleratorFactories::ReadPixels(uint32 texture_id, - uint32 texture_target, - const gfx::Size& size, - const SkBitmap& pixels) { +void RendererGpuVideoDecoderFactories::ReadPixels( + uint32 texture_id, uint32 texture_target, const gfx::Size& size, + const SkBitmap& pixels) { // SkBitmaps use the SkPixelRef object to refcount the underlying pixels. // Multiple SkBitmaps can share a SkPixelRef instance. We use this to // ensure that the underlying pixels in the SkBitmap passed in remain valid @@ -302,13 +232,9 @@ void RendererGpuVideoAcceleratorFactories::ReadPixels(uint32 texture_id, read_pixels_bitmap_.setPixelRef(pixels.pixelRef()); if (!message_loop_->BelongsToCurrentThread()) { - message_loop_->PostTask( - FROM_HERE, - base::Bind(&RendererGpuVideoAcceleratorFactories::AsyncReadPixels, - this, - texture_id, - texture_target, - size)); + message_loop_->PostTask(FROM_HERE, base::Bind( + &RendererGpuVideoDecoderFactories::AsyncReadPixels, this, + texture_id, texture_target, size)); base::WaitableEvent* objects[] = {&aborted_waiter_, &message_loop_async_waiter_}; if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0) @@ -320,10 +246,8 @@ void RendererGpuVideoAcceleratorFactories::ReadPixels(uint32 texture_id, read_pixels_bitmap_.setPixelRef(NULL); } -void RendererGpuVideoAcceleratorFactories::AsyncReadPixels( - uint32 texture_id, - uint32 texture_target, - const gfx::Size& size) { +void RendererGpuVideoDecoderFactories::AsyncReadPixels( + uint32 texture_id, uint32 texture_target, const gfx::Size& size) { DCHECK(message_loop_->BelongsToCurrentThread()); if (!context_.get()) { message_loop_async_waiter_.Signal(); @@ -345,32 +269,25 @@ void RendererGpuVideoAcceleratorFactories::AsyncReadPixels( GLuint fb; gles2->GenFramebuffers(1, &fb); gles2->BindFramebuffer(GL_FRAMEBUFFER, fb); - gles2->FramebufferTexture2D( - GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture_target, tmp_texture, 0); + gles2->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + texture_target, tmp_texture, 0); gles2->PixelStorei(GL_PACK_ALIGNMENT, 4); - gles2->ReadPixels(0, - 0, - size.width(), - size.height(), - GL_BGRA_EXT, - GL_UNSIGNED_BYTE, - read_pixels_bitmap_.pixelRef()->pixels()); + gles2->ReadPixels(0, 0, size.width(), size.height(), GL_BGRA_EXT, + GL_UNSIGNED_BYTE, read_pixels_bitmap_.pixelRef()->pixels()); gles2->DeleteFramebuffers(1, &fb); gles2->DeleteTextures(1, &tmp_texture); DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR)); message_loop_async_waiter_.Signal(); } -base::SharedMemory* RendererGpuVideoAcceleratorFactories::CreateSharedMemory( +base::SharedMemory* RendererGpuVideoDecoderFactories::CreateSharedMemory( size_t size) { if (main_message_loop_->BelongsToCurrentThread()) { return ChildThread::current()->AllocateSharedMemory(size); } - main_message_loop_->PostTask( - FROM_HERE, - base::Bind(&RendererGpuVideoAcceleratorFactories::AsyncCreateSharedMemory, - this, - size)); + main_message_loop_->PostTask(FROM_HERE, base::Bind( + &RendererGpuVideoDecoderFactories::AsyncCreateSharedMemory, this, + size)); base::WaitableEvent* objects[] = {&aborted_waiter_, &render_thread_async_waiter_}; @@ -379,8 +296,7 @@ base::SharedMemory* RendererGpuVideoAcceleratorFactories::CreateSharedMemory( return shared_memory_segment_.release(); } -void RendererGpuVideoAcceleratorFactories::AsyncCreateSharedMemory( - size_t size) { +void RendererGpuVideoDecoderFactories::AsyncCreateSharedMemory(size_t size) { DCHECK_EQ(base::MessageLoop::current(), ChildThread::current()->message_loop()); @@ -390,20 +306,22 @@ void RendererGpuVideoAcceleratorFactories::AsyncCreateSharedMemory( } scoped_refptr<base::MessageLoopProxy> -RendererGpuVideoAcceleratorFactories::GetMessageLoop() { +RendererGpuVideoDecoderFactories::GetMessageLoop() { return message_loop_; } -void RendererGpuVideoAcceleratorFactories::Abort() { aborted_waiter_.Signal(); } +void RendererGpuVideoDecoderFactories::Abort() { + aborted_waiter_.Signal(); +} -bool RendererGpuVideoAcceleratorFactories::IsAborted() { +bool RendererGpuVideoDecoderFactories::IsAborted() { return aborted_waiter_.IsSignaled(); } -scoped_refptr<RendererGpuVideoAcceleratorFactories> -RendererGpuVideoAcceleratorFactories::Clone() { - scoped_refptr<RendererGpuVideoAcceleratorFactories> factories = - new RendererGpuVideoAcceleratorFactories(); +scoped_refptr<media::GpuVideoDecoderFactories> +RendererGpuVideoDecoderFactories::Clone() { + scoped_refptr<RendererGpuVideoDecoderFactories> factories = + new RendererGpuVideoDecoderFactories(); factories->message_loop_ = message_loop_; factories->main_message_loop_ = main_message_loop_; factories->gpu_channel_host_ = gpu_channel_host_; @@ -411,18 +329,10 @@ RendererGpuVideoAcceleratorFactories::Clone() { return factories; } -void -RendererGpuVideoAcceleratorFactories::AsyncDestroyVideoDecodeAccelerator() { +void RendererGpuVideoDecoderFactories::AsyncDestroyVideoDecodeAccelerator() { // OK to release because Destroy() will delete the VDA instance. if (vda_) vda_.release()->Destroy(); } -void -RendererGpuVideoAcceleratorFactories::AsyncDestroyVideoEncodeAccelerator() { - // OK to release because Destroy() will delete the VDA instance. - if (vea_) - vea_.release()->Destroy(); -} - } // namespace content diff --git a/chromium/content/renderer/media/renderer_gpu_video_accelerator_factories.h b/chromium/content/renderer/media/renderer_gpu_video_decoder_factories.h index fcc4ffb411a..32f9bcdf227 100644 --- a/chromium/content/renderer/media/renderer_gpu_video_accelerator_factories.h +++ b/chromium/content/renderer/media/renderer_gpu_video_decoder_factories.h @@ -1,9 +1,9 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. +// 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_RENDERER_MEDIA_RENDERER_GPU_VIDEO_ACCELERATOR_FACTORIES_H_ -#define CONTENT_RENDERER_MEDIA_RENDERER_GPU_VIDEO_ACCELERATOR_FACTORIES_H_ +#ifndef CONTENT_RENDERER_MEDIA_RENDERER_GPU_VIDEO_DECODER_FACTORIES_H_ +#define CONTENT_RENDERER_MEDIA_RENDERER_GPU_VIDEO_DECODER_FACTORIES_H_ #include <vector> @@ -12,7 +12,7 @@ #include "base/memory/weak_ptr.h" #include "base/synchronization/waitable_event.h" #include "content/common/content_export.h" -#include "media/filters/gpu_video_accelerator_factories.h" +#include "media/filters/gpu_video_decoder_factories.h" #include "third_party/skia/include/core/SkBitmap.h" #include "ui/gfx/size.h" @@ -25,7 +25,7 @@ namespace content { class GpuChannelHost; class WebGraphicsContext3DCommandBufferImpl; -// Glue code to expose functionality needed by media::GpuVideoAccelerator to +// Glue code to expose functionality needed by media::GpuVideoDecoder to // RenderViewImpl. This class is entirely an implementation detail of // RenderViewImpl and only has its own header to allow extraction of its // implementation from render_view_impl.cc which is already far too large. @@ -34,31 +34,27 @@ class WebGraphicsContext3DCommandBufferImpl; // internally trampolined to the appropriate thread. GPU/GL-related calls go to // the constructor-argument loop (the media thread), and shmem-related calls go // to the render thread. -class CONTENT_EXPORT RendererGpuVideoAcceleratorFactories - : public media::GpuVideoAcceleratorFactories { +class CONTENT_EXPORT RendererGpuVideoDecoderFactories + : public media::GpuVideoDecoderFactories { public: // Takes a ref on |gpu_channel_host| and tests |context| for loss before each // use. - RendererGpuVideoAcceleratorFactories( + RendererGpuVideoDecoderFactories( GpuChannelHost* gpu_channel_host, const scoped_refptr<base::MessageLoopProxy>& message_loop, WebGraphicsContext3DCommandBufferImpl* wgc3dcbi); - // media::GpuVideoAcceleratorFactories implementation. - virtual scoped_ptr<media::VideoDecodeAccelerator> - CreateVideoDecodeAccelerator( - media::VideoCodecProfile profile, - media::VideoDecodeAccelerator::Client* client) OVERRIDE; - virtual scoped_ptr<media::VideoEncodeAccelerator> - CreateVideoEncodeAccelerator( - media::VideoEncodeAccelerator::Client* client) OVERRIDE; + // media::GpuVideoDecoderFactories implementation. + virtual media::VideoDecodeAccelerator* CreateVideoDecodeAccelerator( + media::VideoCodecProfile profile, + media::VideoDecodeAccelerator::Client* client) OVERRIDE; // Creates textures and produces them into mailboxes. Returns a sync point to // wait on before using the mailboxes, or 0 on failure. - virtual uint32 CreateTextures(int32 count, - const gfx::Size& size, - std::vector<uint32>* texture_ids, - std::vector<gpu::Mailbox>* texture_mailboxes, - uint32 texture_target) OVERRIDE; + virtual uint32 CreateTextures( + int32 count, const gfx::Size& size, + std::vector<uint32>* texture_ids, + std::vector<gpu::Mailbox>* texture_mailboxes, + uint32 texture_target) OVERRIDE; virtual void DeleteTexture(uint32 texture_id) OVERRIDE; virtual void WaitSyncPoint(uint32 sync_point) OVERRIDE; virtual void ReadPixels(uint32 texture_id, @@ -69,14 +65,16 @@ class CONTENT_EXPORT RendererGpuVideoAcceleratorFactories virtual scoped_refptr<base::MessageLoopProxy> GetMessageLoop() OVERRIDE; virtual void Abort() OVERRIDE; virtual bool IsAborted() OVERRIDE; - scoped_refptr<RendererGpuVideoAcceleratorFactories> Clone(); + + // Makes a copy of |this|. + scoped_refptr<media::GpuVideoDecoderFactories> Clone(); protected: - friend class base::RefCountedThreadSafe<RendererGpuVideoAcceleratorFactories>; - virtual ~RendererGpuVideoAcceleratorFactories(); + friend class base::RefCountedThreadSafe<RendererGpuVideoDecoderFactories>; + virtual ~RendererGpuVideoDecoderFactories(); private: - RendererGpuVideoAcceleratorFactories(); + RendererGpuVideoDecoderFactories(); // Helper for the constructor to acquire the ContentGLContext on // |message_loop_|. @@ -87,25 +85,19 @@ class CONTENT_EXPORT RendererGpuVideoAcceleratorFactories // (except for DeleteTexture, which is fire-and-forget). // AsyncCreateSharedMemory runs on the renderer thread and the rest run on // |message_loop_|. - // AsyncCreateVideoDecodeAccelerator returns its output in the |vda_| member. - // AsyncCreateVideoEncodeAccelerator returns its output in the |vea_| member. + // The AsyncCreateVideoDecodeAccelerator returns its output in the vda_ + // member. void AsyncCreateVideoDecodeAccelerator( media::VideoCodecProfile profile, media::VideoDecodeAccelerator::Client* client); - void AsyncCreateVideoEncodeAccelerator( - media::VideoEncodeAccelerator::Client* client); - void AsyncCreateTextures(int32 count, - const gfx::Size& size, - uint32 texture_target, - uint32* sync_point); + void AsyncCreateTextures(int32 count, const gfx::Size& size, + uint32 texture_target, uint32* sync_point); void AsyncDeleteTexture(uint32 texture_id); void AsyncWaitSyncPoint(uint32 sync_point); - void AsyncReadPixels(uint32 texture_id, - uint32 texture_target, + void AsyncReadPixels(uint32 texture_id, uint32 texture_target, const gfx::Size& size); void AsyncCreateSharedMemory(size_t size); void AsyncDestroyVideoDecodeAccelerator(); - void AsyncDestroyVideoEncodeAccelerator(); scoped_refptr<base::MessageLoopProxy> message_loop_; scoped_refptr<base::MessageLoopProxy> main_message_loop_; @@ -124,12 +116,9 @@ class CONTENT_EXPORT RendererGpuVideoAcceleratorFactories // message loop to indicate their completion. e.g. AsyncCreateSharedMemory. base::WaitableEvent render_thread_async_waiter_; - // The vda returned by the CreateVideoDecodeAccelerator function. + // The vda returned by the CreateVideoAcclelerator function. scoped_ptr<media::VideoDecodeAccelerator> vda_; - // The vea returned by the CreateVideoEncodeAccelerator function. - scoped_ptr<media::VideoEncodeAccelerator> vea_; - // Shared memory segment which is returned by the CreateSharedMemory() // function. scoped_ptr<base::SharedMemory> shared_memory_segment_; @@ -141,9 +130,9 @@ class CONTENT_EXPORT RendererGpuVideoAcceleratorFactories std::vector<uint32> created_textures_; std::vector<gpu::Mailbox> created_texture_mailboxes_; - DISALLOW_COPY_AND_ASSIGN(RendererGpuVideoAcceleratorFactories); + DISALLOW_COPY_AND_ASSIGN(RendererGpuVideoDecoderFactories); }; } // namespace content -#endif // CONTENT_RENDERER_MEDIA_RENDERER_GPU_VIDEO_ACCELERATOR_FACTORIES_H_ +#endif // CONTENT_RENDERER_MEDIA_RENDERER_GPU_VIDEO_DECODER_FACTORIES_H_ diff --git a/chromium/content/renderer/media/rtc_video_decoder.cc b/chromium/content/renderer/media/rtc_video_decoder.cc index 27030f69514..12904f11850 100644 --- a/chromium/content/renderer/media/rtc_video_decoder.cc +++ b/chromium/content/renderer/media/rtc_video_decoder.cc @@ -13,7 +13,7 @@ #include "base/task_runner_util.h" #include "content/child/child_thread.h" #include "media/base/bind_to_loop.h" -#include "media/filters/gpu_video_accelerator_factories.h" +#include "media/filters/gpu_video_decoder_factories.h" #include "third_party/webrtc/system_wrappers/interface/ref_count.h" namespace content { @@ -69,7 +69,7 @@ RTCVideoDecoder::BufferData::BufferData() {} RTCVideoDecoder::BufferData::~BufferData() {} RTCVideoDecoder::RTCVideoDecoder( - const scoped_refptr<media::GpuVideoAcceleratorFactories>& factories) + const scoped_refptr<media::GpuVideoDecoderFactories>& factories) : weak_factory_(this), weak_this_(weak_factory_.GetWeakPtr()), factories_(factories), @@ -122,7 +122,7 @@ RTCVideoDecoder::~RTCVideoDecoder() { scoped_ptr<RTCVideoDecoder> RTCVideoDecoder::Create( webrtc::VideoCodecType type, - const scoped_refptr<media::GpuVideoAcceleratorFactories>& factories) { + const scoped_refptr<media::GpuVideoDecoderFactories>& factories) { scoped_ptr<RTCVideoDecoder> decoder; // Convert WebRTC codec type to media codec profile. media::VideoCodecProfile profile; @@ -136,8 +136,8 @@ scoped_ptr<RTCVideoDecoder> RTCVideoDecoder::Create( } decoder.reset(new RTCVideoDecoder(factories)); - decoder->vda_ = - factories->CreateVideoDecodeAccelerator(profile, decoder.get()).Pass(); + decoder->vda_ + .reset(factories->CreateVideoDecodeAccelerator(profile, decoder.get())); // vda can be NULL if VP8 is not supported. if (decoder->vda_ != NULL) { decoder->state_ = INITIALIZED; @@ -397,7 +397,7 @@ scoped_refptr<media::VideoFrame> RTCVideoDecoder::CreateVideoFrame( visible_rect, natural_size, timestamp_ms, - base::Bind(&media::GpuVideoAcceleratorFactories::ReadPixels, + base::Bind(&media::GpuVideoDecoderFactories::ReadPixels, factories_, pb.texture_id(), decoder_texture_target_, diff --git a/chromium/content/renderer/media/rtc_video_decoder.h b/chromium/content/renderer/media/rtc_video_decoder.h index 7a2686e672a..11e58527145 100644 --- a/chromium/content/renderer/media/rtc_video_decoder.h +++ b/chromium/content/renderer/media/rtc_video_decoder.h @@ -30,7 +30,7 @@ class MessageLoopProxy; namespace media { class DecoderBuffer; -class GpuVideoAcceleratorFactories; +class GpuVideoDecoderFactories; } namespace content { @@ -52,7 +52,7 @@ class CONTENT_EXPORT RTCVideoDecoder // run on the message loop of |factories|. static scoped_ptr<RTCVideoDecoder> Create( webrtc::VideoCodecType type, - const scoped_refptr<media::GpuVideoAcceleratorFactories>& factories); + const scoped_refptr<media::GpuVideoDecoderFactories>& factories); // webrtc::VideoDecoder implementation. // Called on WebRTC DecodingThread. @@ -113,7 +113,7 @@ class CONTENT_EXPORT RTCVideoDecoder // The meessage loop of |factories| will be saved to |vda_loop_proxy_|. RTCVideoDecoder( - const scoped_refptr<media::GpuVideoAcceleratorFactories>& factories); + const scoped_refptr<media::GpuVideoDecoderFactories>& factories); void Initialize(base::WaitableEvent* waiter); @@ -197,7 +197,7 @@ class CONTENT_EXPORT RTCVideoDecoder base::WeakPtrFactory<RTCVideoDecoder> weak_factory_; base::WeakPtr<RTCVideoDecoder> weak_this_; - scoped_refptr<media::GpuVideoAcceleratorFactories> factories_; + scoped_refptr<media::GpuVideoDecoderFactories> factories_; // The message loop to run callbacks on. This is from |factories_|. scoped_refptr<base::MessageLoopProxy> vda_loop_proxy_; diff --git a/chromium/content/renderer/media/rtc_video_decoder_factory.cc b/chromium/content/renderer/media/rtc_video_decoder_factory.cc index 57b6a580c3a..e621735dbcc 100644 --- a/chromium/content/renderer/media/rtc_video_decoder_factory.cc +++ b/chromium/content/renderer/media/rtc_video_decoder_factory.cc @@ -6,13 +6,14 @@ #include "base/location.h" #include "base/memory/scoped_ptr.h" -#include "content/renderer/media/renderer_gpu_video_accelerator_factories.h" +#include "content/renderer/media/renderer_gpu_video_decoder_factories.h" #include "content/renderer/media/rtc_video_decoder.h" +#include "media/filters/gpu_video_decoder_factories.h" namespace content { RTCVideoDecoderFactory::RTCVideoDecoderFactory( - const scoped_refptr<RendererGpuVideoAcceleratorFactories>& gpu_factories) + const scoped_refptr<RendererGpuVideoDecoderFactories>& gpu_factories) : gpu_factories_(gpu_factories) { DVLOG(2) << "RTCVideoDecoderFactory"; } @@ -24,7 +25,7 @@ RTCVideoDecoderFactory::~RTCVideoDecoderFactory() { webrtc::VideoDecoder* RTCVideoDecoderFactory::CreateVideoDecoder( webrtc::VideoCodecType type) { DVLOG(2) << "CreateVideoDecoder"; - // GpuVideoAcceleratorFactories is not thread safe. It cannot be shared + // RendererGpuVideoDecoderFactories is not thread safe. It cannot be shared // by different decoders. This method runs on Chrome_libJingle_WorkerThread // and the child thread is blocked while this runs. We cannot create new gpu // factories here. Clone one instead. diff --git a/chromium/content/renderer/media/rtc_video_decoder_factory.h b/chromium/content/renderer/media/rtc_video_decoder_factory.h index f7a42a3cd47..1455d7b61ee 100644 --- a/chromium/content/renderer/media/rtc_video_decoder_factory.h +++ b/chromium/content/renderer/media/rtc_video_decoder_factory.h @@ -11,19 +11,23 @@ #include "third_party/libjingle/source/talk/media/webrtc/webrtcvideodecoderfactory.h" #include "third_party/webrtc/modules/video_coding/codecs/interface/video_codec_interface.h" +namespace media { +class GpuVideoDecoderFactories; +} + namespace webrtc { class VideoDecoder; } namespace content { -class RendererGpuVideoAcceleratorFactories; +class RendererGpuVideoDecoderFactories; // TODO(wuchengli): add unittest. class CONTENT_EXPORT RTCVideoDecoderFactory : NON_EXPORTED_BASE(public cricket::WebRtcVideoDecoderFactory) { public: explicit RTCVideoDecoderFactory( - const scoped_refptr<RendererGpuVideoAcceleratorFactories>& gpu_factories); + const scoped_refptr<RendererGpuVideoDecoderFactories>& gpu_factories); virtual ~RTCVideoDecoderFactory(); // Runs on Chrome_libJingle_WorkerThread. The child thread is blocked while @@ -36,7 +40,7 @@ class CONTENT_EXPORT RTCVideoDecoderFactory virtual void DestroyVideoDecoder(webrtc::VideoDecoder* decoder) OVERRIDE; private: - scoped_refptr<RendererGpuVideoAcceleratorFactories> gpu_factories_; + scoped_refptr<RendererGpuVideoDecoderFactories> gpu_factories_; DISALLOW_COPY_AND_ASSIGN(RTCVideoDecoderFactory); }; diff --git a/chromium/content/renderer/media/rtc_video_decoder_unittest.cc b/chromium/content/renderer/media/rtc_video_decoder_unittest.cc index 3355b6a3386..2ffeb3e4b61 100644 --- a/chromium/content/renderer/media/rtc_video_decoder_unittest.cc +++ b/chromium/content/renderer/media/rtc_video_decoder_unittest.cc @@ -8,7 +8,7 @@ #include "base/threading/thread.h" #include "content/renderer/media/rtc_video_decoder.h" #include "media/base/gmock_callback_support.h" -#include "media/filters/mock_gpu_video_accelerator_factories.h" +#include "media/filters/mock_gpu_video_decoder_factories.h" #include "media/video/mock_video_decode_accelerator.h" #include "testing/gtest/include/gtest/gtest.h" @@ -25,7 +25,7 @@ class RTCVideoDecoderTest : public ::testing::Test, webrtc::DecodedImageCallback { public: RTCVideoDecoderTest() - : mock_gpu_factories_(new media::MockGpuVideoAcceleratorFactories), + : mock_gpu_factories_(new media::MockGpuVideoDecoderFactories), vda_thread_("vda_thread"), idle_waiter_(false, false) { memset(&codec_, 0, sizeof(codec_)); @@ -37,11 +37,11 @@ class RTCVideoDecoderTest : public ::testing::Test, mock_vda_ = new media::MockVideoDecodeAccelerator; EXPECT_CALL(*mock_gpu_factories_, GetMessageLoop()) .WillRepeatedly(Return(vda_loop_proxy_)); - EXPECT_CALL(*mock_gpu_factories_, DoCreateVideoDecodeAccelerator(_, _)) + EXPECT_CALL(*mock_gpu_factories_, CreateVideoDecodeAccelerator(_, _)) .WillRepeatedly( Return(static_cast<media::VideoDecodeAccelerator*>(NULL))); EXPECT_CALL(*mock_gpu_factories_, - DoCreateVideoDecodeAccelerator(media::VP8PROFILE_MAIN, _)) + CreateVideoDecodeAccelerator(media::VP8PROFILE_MAIN, _)) .WillRepeatedly(Return(mock_vda_)); EXPECT_CALL(*mock_gpu_factories_, Abort()).WillRepeatedly(Return()); EXPECT_CALL(*mock_gpu_factories_, CreateSharedMemory(_)) @@ -94,7 +94,7 @@ class RTCVideoDecoderTest : public ::testing::Test, } protected: - scoped_refptr<media::MockGpuVideoAcceleratorFactories> mock_gpu_factories_; + scoped_refptr<media::MockGpuVideoDecoderFactories> mock_gpu_factories_; media::MockVideoDecodeAccelerator* mock_vda_; scoped_ptr<RTCVideoDecoder> rtc_decoder_; webrtc::VideoCodec codec_; diff --git a/chromium/content/renderer/media/rtc_video_encoder.cc b/chromium/content/renderer/media/rtc_video_encoder.cc deleted file mode 100644 index 416317d3635..00000000000 --- a/chromium/content/renderer/media/rtc_video_encoder.cc +++ /dev/null @@ -1,658 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/renderer/media/rtc_video_encoder.h" - -#include "base/bind.h" -#include "base/location.h" -#include "base/logging.h" -#include "base/memory/scoped_vector.h" -#include "base/message_loop/message_loop_proxy.h" -#include "base/synchronization/waitable_event.h" -#include "content/renderer/media/renderer_gpu_video_accelerator_factories.h" -#include "media/base/bitstream_buffer.h" -#include "media/base/video_frame.h" -#include "media/filters/gpu_video_accelerator_factories.h" -#include "media/video/video_encode_accelerator.h" - -#define NOTIFY_ERROR(x) \ - do { \ - DLOG(ERROR) << "calling NotifyError(): " << x; \ - NotifyError(x); \ - } while (0) - -namespace content { - -// This private class of RTCVideoEncoder does the actual work of communicating -// with a media::VideoEncodeAccelerator for handling video encoding. It can -// be created on any thread, but should subsequently be posted to (and Destroy() -// called on) a single thread. Callbacks to RTCVideoEncoder are posted to the -// thread on which the instance was constructed. -// -// This class separates state related to the thread that RTCVideoEncoder -// operates on (presently the libjingle worker thread) from the thread that -// |gpu_factories_| provides for accelerator operations (presently the media -// thread). The RTCVideoEncoder class can be deleted directly by WebRTC, while -// RTCVideoEncoder::Impl stays around long enough to properly shut down the VEA. -class RTCVideoEncoder::Impl - : public media::VideoEncodeAccelerator::Client, - public base::RefCountedThreadSafe<RTCVideoEncoder::Impl> { - public: - Impl( - const base::WeakPtr<RTCVideoEncoder>& weak_encoder, - const scoped_refptr<RendererGpuVideoAcceleratorFactories>& gpu_factories); - - // Create the VEA and call Initialize() on it. Called once per instantiation, - // and then the instance is bound forevermore to whichever thread made the - // call. - // RTCVideoEncoder expects to be able to call this function synchronously from - // its own thread, hence the |async_waiter| and |async_retval| arguments. - void CreateAndInitializeVEA(const gfx::Size& input_visible_size, - uint32 bitrate, - media::VideoCodecProfile profile, - base::WaitableEvent* async_waiter, - int32_t* async_retval); - // Enqueue a frame from WebRTC for encoding. - // RTCVideoEncoder expects to be able to call this function synchronously from - // its own thread, hence the |async_waiter| and |async_retval| arguments. - void Enqueue(const webrtc::I420VideoFrame* input_frame, - bool force_keyframe, - base::WaitableEvent* async_waiter, - int32_t* async_retval); - - // RTCVideoEncoder is given a buffer to be passed to WebRTC through the - // RTCVideoEncoder::ReturnEncodedImage() function. When that is complete, - // the buffer is returned to Impl by its index using this function. - void UseOutputBitstreamBufferId(int32 bitstream_buffer_id); - - // Request encoding parameter change for the underlying encoder. - void RequestEncodingParametersChange(uint32 bitrate, uint32 framerate); - - // Destroy this Impl's encoder. The destructor is not explicitly called, as - // Impl is a base::RefCountedThreadSafe. - void Destroy(); - - // media::VideoEncodeAccelerator::Client implementation. - virtual void NotifyInitializeDone() OVERRIDE; - virtual void RequireBitstreamBuffers(unsigned int input_count, - const gfx::Size& input_coded_size, - size_t output_buffer_size) OVERRIDE; - virtual void BitstreamBufferReady(int32 bitstream_buffer_id, - size_t payload_size, - bool key_frame) OVERRIDE; - virtual void NotifyError(media::VideoEncodeAccelerator::Error error) OVERRIDE; - - private: - friend class base::RefCountedThreadSafe<Impl>; - - enum { - kInputBufferExtraCount = 1, // The number of input buffers allocated, more - // than what is requested by - // VEA::RequireBitstreamBuffers(). - kOutputBufferCount = 3, - }; - - virtual ~Impl(); - - // Perform encoding on an input frame from the input queue. - void EncodeOneFrame(); - - // Notify that an input frame is finished for encoding. |index| is the index - // of the completed frame in |input_buffers_|. - void EncodeFrameFinished(int index); - - // Set up/signal |async_waiter_| and |async_retval_|; see declarations below. - void RegisterAsyncWaiter(base::WaitableEvent* waiter, int32_t* retval); - void SignalAsyncWaiter(int32_t retval); - - base::ThreadChecker thread_checker_; - - // Weak pointer to the parent RTCVideoEncoder, for posting back VEA::Client - // notifications. - const base::WeakPtr<RTCVideoEncoder> weak_encoder_; - - // The message loop on which to post callbacks to |weak_encoder_|. - const scoped_refptr<base::MessageLoopProxy> encoder_message_loop_proxy_; - - // Factory for creating VEAs, shared memory buffers, etc. - const scoped_refptr<RendererGpuVideoAcceleratorFactories> gpu_factories_; - - // webrtc::VideoEncoder expects InitEncode() and Encode() to be synchronous. - // Do this by waiting on the |async_waiter_| and returning the return value in - // |async_retval_| when initialization completes, encoding completes, or - // an error occurs. - base::WaitableEvent* async_waiter_; - int32_t* async_retval_; - - // The underlying VEA to perform encoding on. - scoped_ptr<media::VideoEncodeAccelerator> video_encoder_; - - // Next input frame. Since there is at most one next frame, a single-element - // queue is sufficient. - const webrtc::I420VideoFrame* input_next_frame_; - - // Whether to encode a keyframe next. - bool input_next_frame_keyframe_; - - // Frame sizes. - gfx::Size input_frame_coded_size_; - gfx::Size input_visible_size_; - - // Shared memory buffers for input/output with the VEA. - ScopedVector<base::SharedMemory> input_buffers_; - ScopedVector<base::SharedMemory> output_buffers_; - - // Input buffers ready to be filled with input from Encode(). As a LIFO since - // we don't care about ordering. - std::vector<int> input_buffers_free_; - - // Timestamp of first frame returned from encoder. We calculate subsequent - // capture times as deltas from this base. - base::Time time_base_; - - DISALLOW_COPY_AND_ASSIGN(Impl); -}; - -RTCVideoEncoder::Impl::Impl( - const base::WeakPtr<RTCVideoEncoder>& weak_encoder, - const scoped_refptr<RendererGpuVideoAcceleratorFactories>& gpu_factories) - : weak_encoder_(weak_encoder), - encoder_message_loop_proxy_(base::MessageLoopProxy::current()), - gpu_factories_(gpu_factories), - async_waiter_(NULL), - async_retval_(NULL), - input_next_frame_(NULL), - input_next_frame_keyframe_(false) { - thread_checker_.DetachFromThread(); -} - -void RTCVideoEncoder::Impl::CreateAndInitializeVEA( - const gfx::Size& input_visible_size, - uint32 bitrate, - media::VideoCodecProfile profile, - base::WaitableEvent* async_waiter, - int32_t* async_retval) { - DVLOG(3) << "Impl::CreateAndInitializeVEA()"; - DCHECK(thread_checker_.CalledOnValidThread()); - - RegisterAsyncWaiter(async_waiter, async_retval); - - // Check for overflow converting bitrate (kilobits/sec) to bits/sec. - if (bitrate > kuint32max / 1000) { - NOTIFY_ERROR(media::VideoEncodeAccelerator::kInvalidArgumentError); - return; - } - - video_encoder_ = gpu_factories_->CreateVideoEncodeAccelerator(this).Pass(); - if (!video_encoder_) { - NOTIFY_ERROR(media::VideoEncodeAccelerator::kPlatformFailureError); - return; - } - input_visible_size_ = input_visible_size; - video_encoder_->Initialize( - media::VideoFrame::I420, input_visible_size_, profile, bitrate * 1000); -} - -void RTCVideoEncoder::Impl::Enqueue(const webrtc::I420VideoFrame* input_frame, - bool force_keyframe, - base::WaitableEvent* async_waiter, - int32_t* async_retval) { - DVLOG(3) << "Impl::Enqueue()"; - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(!input_next_frame_); - - RegisterAsyncWaiter(async_waiter, async_retval); - input_next_frame_ = input_frame; - input_next_frame_keyframe_ = force_keyframe; - - if (!input_buffers_free_.empty()) - EncodeOneFrame(); -} - -void RTCVideoEncoder::Impl::UseOutputBitstreamBufferId( - int32 bitstream_buffer_id) { - DVLOG(3) << "Impl::UseOutputBitstreamBufferIndex(): " - "bitstream_buffer_id=" << bitstream_buffer_id; - DCHECK(thread_checker_.CalledOnValidThread()); - if (video_encoder_) { - video_encoder_->UseOutputBitstreamBuffer(media::BitstreamBuffer( - bitstream_buffer_id, - output_buffers_[bitstream_buffer_id]->handle(), - output_buffers_[bitstream_buffer_id]->mapped_size())); - } -} - -void RTCVideoEncoder::Impl::RequestEncodingParametersChange(uint32 bitrate, - uint32 framerate) { - DVLOG(3) << "Impl::RequestEncodingParametersChange(): bitrate=" << bitrate - << ", framerate=" << framerate; - DCHECK(thread_checker_.CalledOnValidThread()); - - // Check for overflow converting bitrate (kilobits/sec) to bits/sec. - if (bitrate > kuint32max / 1000) { - NOTIFY_ERROR(media::VideoEncodeAccelerator::kInvalidArgumentError); - return; - } - - if (video_encoder_) - video_encoder_->RequestEncodingParametersChange(bitrate * 1000, framerate); -} - -void RTCVideoEncoder::Impl::Destroy() { - DVLOG(3) << "Impl::Destroy()"; - DCHECK(thread_checker_.CalledOnValidThread()); - if (video_encoder_) - video_encoder_.release()->Destroy(); -} - -void RTCVideoEncoder::Impl::NotifyInitializeDone() { - DVLOG(3) << "Impl::NotifyInitializeDone()"; - DCHECK(thread_checker_.CalledOnValidThread()); - SignalAsyncWaiter(WEBRTC_VIDEO_CODEC_OK); -} - -void RTCVideoEncoder::Impl::RequireBitstreamBuffers( - unsigned int input_count, - const gfx::Size& input_coded_size, - size_t output_buffer_size) { - DVLOG(3) << "Impl::RequireBitstreamBuffers(): input_count=" << input_count - << ", input_coded_size=" << input_coded_size.ToString() - << ", output_buffer_size=" << output_buffer_size; - DCHECK(thread_checker_.CalledOnValidThread()); - - if (!video_encoder_) - return; - - input_frame_coded_size_ = input_coded_size; - - for (unsigned int i = 0; i < input_count + kInputBufferExtraCount; ++i) { - base::SharedMemory* shm = - gpu_factories_->CreateSharedMemory(input_coded_size.GetArea() * 3 / 2); - if (!shm) { - DLOG(ERROR) << "Impl::RequireBitstreamBuffers(): " - "failed to create input buffer " << i; - NOTIFY_ERROR(media::VideoEncodeAccelerator::kPlatformFailureError); - return; - } - input_buffers_.push_back(shm); - input_buffers_free_.push_back(i); - } - - for (int i = 0; i < kOutputBufferCount; ++i) { - base::SharedMemory* shm = - gpu_factories_->CreateSharedMemory(output_buffer_size); - if (!shm) { - DLOG(ERROR) << "Impl::RequireBitstreamBuffers(): " - "failed to create output buffer " << i; - NOTIFY_ERROR(media::VideoEncodeAccelerator::kPlatformFailureError); - return; - } - output_buffers_.push_back(shm); - } - - // Immediately provide all output buffers to the VEA. - for (size_t i = 0; i < output_buffers_.size(); ++i) { - video_encoder_->UseOutputBitstreamBuffer(media::BitstreamBuffer( - i, output_buffers_[i]->handle(), output_buffers_[i]->mapped_size())); - } -} - -void RTCVideoEncoder::Impl::BitstreamBufferReady(int32 bitstream_buffer_id, - size_t payload_size, - bool key_frame) { - DVLOG(3) << "Impl::BitstreamBufferReady(): " - "bitstream_buffer_id=" << bitstream_buffer_id - << ", payload_size=" << payload_size - << ", key_frame=" << key_frame; - DCHECK(thread_checker_.CalledOnValidThread()); - - if (bitstream_buffer_id < 0 || - bitstream_buffer_id >= static_cast<int>(output_buffers_.size())) { - DLOG(ERROR) << "Impl::BitstreamBufferReady(): invalid bitstream_buffer_id=" - << bitstream_buffer_id; - NOTIFY_ERROR(media::VideoEncodeAccelerator::kPlatformFailureError); - return; - } - base::SharedMemory* output_buffer = output_buffers_[bitstream_buffer_id]; - if (payload_size > output_buffer->mapped_size()) { - DLOG(ERROR) << "Impl::BitstreamBufferReady(): invalid payload_size=" - << payload_size; - NOTIFY_ERROR(media::VideoEncodeAccelerator::kPlatformFailureError); - return; - } - - const base::Time now = base::Time::Now(); - if (time_base_.is_null()) - time_base_ = now; - const base::TimeDelta delta = now - time_base_; - - scoped_ptr<webrtc::EncodedImage> image(new webrtc::EncodedImage( - reinterpret_cast<uint8_t*>(output_buffer->memory()), - payload_size, - output_buffer->mapped_size())); - image->_encodedWidth = input_visible_size_.width(); - image->_encodedHeight = input_visible_size_.height(); - // Convert capture time to 90 kHz RTP timestamp. - image->_timeStamp = (delta * 90000).InSeconds(); - image->capture_time_ms_ = delta.InMilliseconds(); - image->_frameType = (key_frame ? webrtc::kKeyFrame : webrtc::kDeltaFrame); - image->_completeFrame = true; - - encoder_message_loop_proxy_->PostTask( - FROM_HERE, - base::Bind(&RTCVideoEncoder::ReturnEncodedImage, - weak_encoder_, - base::Passed(&image), - bitstream_buffer_id)); -} - -void RTCVideoEncoder::Impl::NotifyError( - media::VideoEncodeAccelerator::Error error) { - DVLOG(3) << "Impl::NotifyError(): error=" << error; - DCHECK(thread_checker_.CalledOnValidThread()); - int32_t retval; - switch (error) { - case media::VideoEncodeAccelerator::kInvalidArgumentError: - retval = WEBRTC_VIDEO_CODEC_ERR_PARAMETER; - break; - default: - retval = WEBRTC_VIDEO_CODEC_ERROR; - } - - if (video_encoder_) - video_encoder_.release()->Destroy(); - - if (async_waiter_) { - SignalAsyncWaiter(retval); - } else { - encoder_message_loop_proxy_->PostTask( - FROM_HERE, - base::Bind(&RTCVideoEncoder::NotifyError, weak_encoder_, retval)); - } -} - -RTCVideoEncoder::Impl::~Impl() { DCHECK(!video_encoder_); } - -void RTCVideoEncoder::Impl::EncodeOneFrame() { - DVLOG(3) << "Impl::EncodeOneFrame()"; - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(input_next_frame_); - DCHECK(!input_buffers_free_.empty()); - - // EncodeOneFrame() may re-enter EncodeFrameFinished() if VEA::Encode() fails, - // we receive a VEA::NotifyError(), and the media::VideoFrame we pass to - // Encode() gets destroyed early. Handle this by resetting our - // input_next_frame_* state before we hand off the VideoFrame to the VEA. - const webrtc::I420VideoFrame* next_frame = input_next_frame_; - bool next_frame_keyframe = input_next_frame_keyframe_; - input_next_frame_ = NULL; - input_next_frame_keyframe_ = false; - - if (!video_encoder_) { - SignalAsyncWaiter(WEBRTC_VIDEO_CODEC_ERROR); - return; - } - - const int index = input_buffers_free_.back(); - base::SharedMemory* input_buffer = input_buffers_[index]; - - // Do a strided copy of the input frame to match the input requirements for - // the encoder. - // TODO(sheu): support zero-copy from WebRTC. http://crbug.com/269312 - const uint8_t* src = next_frame->buffer(webrtc::kYPlane); - uint8* dst = reinterpret_cast<uint8*>(input_buffer->memory()); - uint8* const y_dst = dst; - int width = input_frame_coded_size_.width(); - int stride = next_frame->stride(webrtc::kYPlane); - for (int i = 0; i < next_frame->height(); ++i) { - memcpy(dst, src, width); - src += stride; - dst += width; - } - src = next_frame->buffer(webrtc::kUPlane); - width = input_frame_coded_size_.width() / 2; - stride = next_frame->stride(webrtc::kUPlane); - for (int i = 0; i < next_frame->height() / 2; ++i) { - memcpy(dst, src, width); - src += stride; - dst += width; - } - src = next_frame->buffer(webrtc::kVPlane); - width = input_frame_coded_size_.width() / 2; - stride = next_frame->stride(webrtc::kVPlane); - for (int i = 0; i < next_frame->height() / 2; ++i) { - memcpy(dst, src, width); - src += stride; - dst += width; - } - - scoped_refptr<media::VideoFrame> frame = - media::VideoFrame::WrapExternalSharedMemory( - media::VideoFrame::I420, - input_frame_coded_size_, - gfx::Rect(input_visible_size_), - input_visible_size_, - y_dst, - input_buffer->handle(), - base::TimeDelta(), - base::Bind(&RTCVideoEncoder::Impl::EncodeFrameFinished, this, index)); - - video_encoder_->Encode(frame, next_frame_keyframe); - input_buffers_free_.pop_back(); - SignalAsyncWaiter(WEBRTC_VIDEO_CODEC_OK); -} - -void RTCVideoEncoder::Impl::EncodeFrameFinished(int index) { - DVLOG(3) << "Impl::EncodeFrameFinished(): index=" << index; - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK_GE(index, 0); - DCHECK_LT(index, static_cast<int>(input_buffers_.size())); - input_buffers_free_.push_back(index); - if (input_next_frame_) - EncodeOneFrame(); -} - -void RTCVideoEncoder::Impl::RegisterAsyncWaiter(base::WaitableEvent* waiter, - int32_t* retval) { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(!async_waiter_); - DCHECK(!async_retval_); - async_waiter_ = waiter; - async_retval_ = retval; -} - -void RTCVideoEncoder::Impl::SignalAsyncWaiter(int32_t retval) { - DCHECK(thread_checker_.CalledOnValidThread()); - *async_retval_ = retval; - async_waiter_->Signal(); - async_retval_ = NULL; - async_waiter_ = NULL; -} - -#undef NOTIFY_ERROR - -//////////////////////////////////////////////////////////////////////////////// -// -// RTCVideoEncoder -// -//////////////////////////////////////////////////////////////////////////////// - -RTCVideoEncoder::RTCVideoEncoder( - webrtc::VideoCodecType type, - media::VideoCodecProfile profile, - const scoped_refptr<RendererGpuVideoAcceleratorFactories>& gpu_factories) - : video_codec_type_(type), - video_codec_profile_(profile), - gpu_factories_(gpu_factories), - encoded_image_callback_(NULL), - impl_status_(WEBRTC_VIDEO_CODEC_UNINITIALIZED) { - DVLOG(1) << "RTCVideoEncoder(): profile=" << profile; -} - -RTCVideoEncoder::~RTCVideoEncoder() { - DCHECK(thread_checker_.CalledOnValidThread()); - Release(); - DCHECK(!impl_); -} - -int32_t RTCVideoEncoder::InitEncode(const webrtc::VideoCodec* codec_settings, - int32_t number_of_cores, - uint32_t max_payload_size) { - DVLOG(1) << "InitEncode(): codecType=" << codec_settings->codecType - << ", width=" << codec_settings->width - << ", height=" << codec_settings->height - << ", startBitrate=" << codec_settings->startBitrate; - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(!impl_); - - weak_this_factory_.reset(new base::WeakPtrFactory<RTCVideoEncoder>(this)); - impl_ = new Impl(weak_this_factory_->GetWeakPtr(), gpu_factories_); - base::WaitableEvent initialization_waiter(true, false); - int32_t initialization_retval = WEBRTC_VIDEO_CODEC_UNINITIALIZED; - gpu_factories_->GetMessageLoop()->PostTask( - FROM_HERE, - base::Bind(&RTCVideoEncoder::Impl::CreateAndInitializeVEA, - impl_, - gfx::Size(codec_settings->width, codec_settings->height), - codec_settings->startBitrate, - video_codec_profile_, - &initialization_waiter, - &initialization_retval)); - - // webrtc::VideoEncoder expects this call to be synchronous. - initialization_waiter.Wait(); - return initialization_retval; -} - -int32_t RTCVideoEncoder::Encode( - const webrtc::I420VideoFrame& input_image, - const webrtc::CodecSpecificInfo* codec_specific_info, - const std::vector<webrtc::VideoFrameType>* frame_types) { - DVLOG(3) << "Encode()"; - // TODO(sheu): figure out why this check fails. - // DCHECK(thread_checker_.CalledOnValidThread()); - if (!impl_) { - DVLOG(3) << "Encode(): returning impl_status_=" << impl_status_; - return impl_status_; - } - - base::WaitableEvent encode_waiter(true, false); - int32_t encode_retval = WEBRTC_VIDEO_CODEC_UNINITIALIZED; - gpu_factories_->GetMessageLoop()->PostTask( - FROM_HERE, - base::Bind(&RTCVideoEncoder::Impl::Enqueue, - impl_, - &input_image, - (frame_types->front() == webrtc::kKeyFrame), - &encode_waiter, - &encode_retval)); - - // webrtc::VideoEncoder expects this call to be synchronous. - encode_waiter.Wait(); - DVLOG(3) << "Encode(): returning encode_retval=" << encode_retval; - return encode_retval; -} - -int32_t RTCVideoEncoder::RegisterEncodeCompleteCallback( - webrtc::EncodedImageCallback* callback) { - DVLOG(3) << "RegisterEncodeCompleteCallback()"; - DCHECK(thread_checker_.CalledOnValidThread()); - if (!impl_) { - DVLOG(3) << "RegisterEncodeCompleteCallback(): returning " << impl_status_; - return impl_status_; - } - - encoded_image_callback_ = callback; - return WEBRTC_VIDEO_CODEC_OK; -} - -int32_t RTCVideoEncoder::Release() { - DVLOG(3) << "Release()"; - DCHECK(thread_checker_.CalledOnValidThread()); - - // Reset the gpu_factory_, in case we reuse this encoder. - gpu_factories_->Abort(); - gpu_factories_ = gpu_factories_->Clone(); - if (impl_) { - gpu_factories_->GetMessageLoop()->PostTask( - FROM_HERE, base::Bind(&RTCVideoEncoder::Impl::Destroy, impl_)); - impl_ = NULL; - weak_this_factory_.reset(); - impl_status_ = WEBRTC_VIDEO_CODEC_UNINITIALIZED; - } - return WEBRTC_VIDEO_CODEC_OK; -} - -int32_t RTCVideoEncoder::SetChannelParameters(uint32_t packet_loss, int rtt) { - DVLOG(3) << "SetChannelParameters(): packet_loss=" << packet_loss - << ", rtt=" << rtt; - DCHECK(thread_checker_.CalledOnValidThread()); - // Ignored. - return WEBRTC_VIDEO_CODEC_OK; -} - -int32_t RTCVideoEncoder::SetRates(uint32_t new_bit_rate, uint32_t frame_rate) { - DVLOG(3) << "SetRates(): new_bit_rate=" << new_bit_rate - << ", frame_rate=" << frame_rate; - DCHECK(thread_checker_.CalledOnValidThread()); - if (!impl_) { - DVLOG(3) << "SetRates(): returning " << impl_status_; - return impl_status_; - } - - gpu_factories_->GetMessageLoop()->PostTask( - FROM_HERE, - base::Bind(&RTCVideoEncoder::Impl::RequestEncodingParametersChange, - impl_, - new_bit_rate, - frame_rate)); - return WEBRTC_VIDEO_CODEC_OK; -} - -void RTCVideoEncoder::ReturnEncodedImage(scoped_ptr<webrtc::EncodedImage> image, - int32 bitstream_buffer_id) { - DCHECK(thread_checker_.CalledOnValidThread()); - DVLOG(3) << "ReturnEncodedImage(): " - "bitstream_buffer_id=" << bitstream_buffer_id; - - if (!encoded_image_callback_) - return; - - webrtc::CodecSpecificInfo info; - info.codecType = video_codec_type_; - - // Generate a header describing a single fragment. - webrtc::RTPFragmentationHeader header; - header.VerifyAndAllocateFragmentationHeader(1); - header.fragmentationOffset[0] = 0; - header.fragmentationLength[0] = image->_length; - header.fragmentationPlType[0] = 0; - header.fragmentationTimeDiff[0] = 0; - - int32_t retval = encoded_image_callback_->Encoded(*image, &info, &header); - if (retval < 0) { - DVLOG(2) << "ReturnEncodedImage(): encoded_image_callback_ returned " - << retval; - } - - // The call through webrtc::EncodedImageCallback is synchronous, so we can - // immediately recycle the output buffer back to the Impl. - gpu_factories_->GetMessageLoop()->PostTask( - FROM_HERE, - base::Bind(&RTCVideoEncoder::Impl::UseOutputBitstreamBufferId, - impl_, - bitstream_buffer_id)); -} - -void RTCVideoEncoder::NotifyError(int32_t error) { - DCHECK(thread_checker_.CalledOnValidThread()); - DVLOG(1) << "NotifyError(): error=" << error; - - impl_status_ = error; - gpu_factories_->GetMessageLoop()->PostTask( - FROM_HERE, base::Bind(&RTCVideoEncoder::Impl::Destroy, impl_)); - impl_ = NULL; -} - -} // namespace content diff --git a/chromium/content/renderer/media/rtc_video_encoder.h b/chromium/content/renderer/media/rtc_video_encoder.h deleted file mode 100644 index 22d4c503d3a..00000000000 --- a/chromium/content/renderer/media/rtc_video_encoder.h +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_RENDERER_MEDIA_RTC_VIDEO_ENCODER_H_ -#define CONTENT_RENDERER_MEDIA_RTC_VIDEO_ENCODER_H_ - -#include <vector> - -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" -#include "base/memory/weak_ptr.h" -#include "base/threading/thread_checker.h" -#include "base/time/time.h" -#include "content/common/content_export.h" -#include "media/base/video_decoder_config.h" -#include "third_party/webrtc/modules/video_coding/codecs/interface/video_codec_interface.h" -#include "ui/gfx/size.h" - -namespace base { - -class MessageLoopProxy; - -} // namespace base - -namespace content { - -class RendererGpuVideoAcceleratorFactories; - -// RTCVideoEncoder uses a media::VideoEncodeAccelerator to implement a -// webrtc::VideoEncoder class for WebRTC. Internally, VEA methods are -// trampolined to a private RTCVideoEncoder::Impl instance. The Impl class runs -// on the worker thread queried from the |gpu_factories_|, which is presently -// the media thread. RTCVideoEncoder itself is run and destroyed on the thread -// it is constructed on, which is presently the libjingle worker thread. -// Callbacks from the Impl due to its VEA::Client notifications are also posted -// back to RTCVideoEncoder on this thread. -class CONTENT_EXPORT RTCVideoEncoder - : NON_EXPORTED_BASE(public webrtc::VideoEncoder) { - public: - RTCVideoEncoder( - webrtc::VideoCodecType type, - media::VideoCodecProfile profile, - const scoped_refptr<RendererGpuVideoAcceleratorFactories>& gpu_factories); - virtual ~RTCVideoEncoder(); - - // webrtc::VideoEncoder implementation. Tasks are posted to |impl_| using the - // appropriate VEA methods. - virtual int32_t InitEncode(const webrtc::VideoCodec* codec_settings, - int32_t number_of_cores, - uint32_t max_payload_size) OVERRIDE; - virtual int32_t Encode( - const webrtc::I420VideoFrame& input_image, - const webrtc::CodecSpecificInfo* codec_specific_info, - const std::vector<webrtc::VideoFrameType>* frame_types) OVERRIDE; - virtual int32_t RegisterEncodeCompleteCallback( - webrtc::EncodedImageCallback* callback) OVERRIDE; - virtual int32_t Release() OVERRIDE; - virtual int32_t SetChannelParameters(uint32_t packet_loss, int rtt) OVERRIDE; - virtual int32_t SetRates(uint32_t new_bit_rate, uint32_t frame_rate) OVERRIDE; - - private: - class Impl; - friend class RTCVideoEncoder::Impl; - - // Return an encoded output buffer to WebRTC. - void ReturnEncodedImage(scoped_ptr<webrtc::EncodedImage> image, - int32 bitstream_buffer_id); - - void NotifyError(int32_t error); - - base::ThreadChecker thread_checker_; - - // The video codec type, as reported to WebRTC. - const webrtc::VideoCodecType video_codec_type_; - - // The video codec profile, to configure the encoder to encode to. - const media::VideoCodecProfile video_codec_profile_; - - // Factory for creating VEAs, shared memory buffers, etc. - scoped_refptr<RendererGpuVideoAcceleratorFactories> gpu_factories_; - - // Weak pointer and factory for posting back VEA::Client notifications to - // RTCVideoEncoder. - scoped_ptr<base::WeakPtrFactory<RTCVideoEncoder> > weak_this_factory_; - - // webrtc::VideoEncoder encode complete callback. - webrtc::EncodedImageCallback* encoded_image_callback_; - - // The RTCVideoEncoder::Impl that does all the work. - scoped_refptr<Impl> impl_; - - // We cannot immediately return error conditions to the WebRTC user of this - // class, as there is no error callback in the webrtc::VideoEncoder interface. - // Instead, we cache an error status here and return it the next time an - // interface entry point is called. - int32_t impl_status_; - - DISALLOW_COPY_AND_ASSIGN(RTCVideoEncoder); -}; - -} // namespace content - -#endif // CONTENT_RENDERER_MEDIA_RTC_VIDEO_ENCODER_H_ diff --git a/chromium/content/renderer/media/rtc_video_encoder_factory.cc b/chromium/content/renderer/media/rtc_video_encoder_factory.cc deleted file mode 100644 index 3ff42728df2..00000000000 --- a/chromium/content/renderer/media/rtc_video_encoder_factory.cc +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/renderer/media/rtc_video_encoder_factory.h" - -#include "content/common/gpu/client/gpu_video_encode_accelerator_host.h" -#include "content/renderer/media/renderer_gpu_video_accelerator_factories.h" -#include "content/renderer/media/rtc_video_encoder.h" -#include "media/video/video_encode_accelerator.h" - -namespace content { - -namespace { - -// Translate from media::VideoEncodeAccelerator::SupportedProfile to -// cricket::WebRtcVideoEncoderFactory::VideoCodec -cricket::WebRtcVideoEncoderFactory::VideoCodec VEAToWebRTCCodec( - const media::VideoEncodeAccelerator::SupportedProfile& profile) { - webrtc::VideoCodecType type = webrtc::kVideoCodecUnknown; - std::string name; - int width = 0, height = 0, fps = 0; - - if (profile.profile >= media::VP8PROFILE_MIN && - profile.profile <= media::VP8PROFILE_MAX) { - type = webrtc::kVideoCodecVP8; - name = "VP8"; - } else if (profile.profile >= media::H264PROFILE_MIN && - profile.profile <= media::H264PROFILE_MAX) { - type = webrtc::kVideoCodecGeneric; - name = "CAST1"; - } - - if (type != webrtc::kVideoCodecUnknown) { - width = profile.max_resolution.width(); - height = profile.max_resolution.height(); - fps = profile.max_framerate.numerator; - DCHECK_EQ(profile.max_framerate.denominator, 1U); - } - - return cricket::WebRtcVideoEncoderFactory::VideoCodec( - type, name, width, height, fps); -} - -// Translate from cricket::WebRtcVideoEncoderFactory::VideoCodec to -// media::VideoCodecProfile. Pick a default profile for each codec type. -media::VideoCodecProfile WebRTCCodecToVideoCodecProfile( - webrtc::VideoCodecType type) { - switch (type) { - case webrtc::kVideoCodecVP8: - return media::VP8PROFILE_MAIN; - case webrtc::kVideoCodecGeneric: - return media::H264PROFILE_MAIN; - default: - return media::VIDEO_CODEC_PROFILE_UNKNOWN; - } -} - -} // anonymous namespace - -RTCVideoEncoderFactory::RTCVideoEncoderFactory( - const scoped_refptr<RendererGpuVideoAcceleratorFactories>& gpu_factories) - : gpu_factories_(gpu_factories) { - // Query media::VideoEncodeAccelerator (statically) for our supported codecs. - std::vector<media::VideoEncodeAccelerator::SupportedProfile> profiles = - GpuVideoEncodeAcceleratorHost::GetSupportedProfiles(); - for (size_t i = 0; i < profiles.size(); ++i) { - VideoCodec codec = VEAToWebRTCCodec(profiles[i]); - if (codec.type != webrtc::kVideoCodecUnknown) - codecs_.push_back(codec); - } -} - -RTCVideoEncoderFactory::~RTCVideoEncoderFactory() {} - -webrtc::VideoEncoder* RTCVideoEncoderFactory::CreateVideoEncoder( - webrtc::VideoCodecType type) { - bool found = false; - for (size_t i = 0; i < codecs_.size(); ++i) { - if (codecs_[i].type == type) { - found = true; - break; - } - } - if (!found) - return NULL; - // GpuVideoAcceleratorFactories is not thread safe. It cannot be shared - // by different encoders. Since we aren't running on the child thread and - // cannot create a new factory, clone one instead. - return new RTCVideoEncoder( - type, WebRTCCodecToVideoCodecProfile(type), gpu_factories_->Clone()); -} - -void RTCVideoEncoderFactory::AddObserver(Observer* observer) { - // No-op: our codec list is populated on installation. -} - -void RTCVideoEncoderFactory::RemoveObserver(Observer* observer) {} - -const std::vector<cricket::WebRtcVideoEncoderFactory::VideoCodec>& -RTCVideoEncoderFactory::codecs() const { - return codecs_; -} - -void RTCVideoEncoderFactory::DestroyVideoEncoder( - webrtc::VideoEncoder* encoder) { - delete encoder; -} - -} // namespace content diff --git a/chromium/content/renderer/media/rtc_video_encoder_factory.h b/chromium/content/renderer/media/rtc_video_encoder_factory.h deleted file mode 100644 index b07ccda0043..00000000000 --- a/chromium/content/renderer/media/rtc_video_encoder_factory.h +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_RENDERER_MEDIA_RTC_VIDEO_ENCODER_FACTORY_H_ -#define CONTENT_RENDERER_MEDIA_RTC_VIDEO_ENCODER_FACTORY_H_ - -#include <vector> - -#include "base/compiler_specific.h" -#include "base/memory/ref_counted.h" -#include "content/common/content_export.h" -#include "third_party/libjingle/source/talk/media/webrtc/webrtcvideoencoderfactory.h" - -namespace content { - -class RendererGpuVideoAcceleratorFactories; - -// This class creates RTCVideoEncoder instances (each wrapping a -// media::VideoEncodeAccelerator) on behalf of the WebRTC stack. -class CONTENT_EXPORT RTCVideoEncoderFactory - : NON_EXPORTED_BASE(public cricket::WebRtcVideoEncoderFactory) { - public: - explicit RTCVideoEncoderFactory( - const scoped_refptr<RendererGpuVideoAcceleratorFactories>& gpu_factories); - virtual ~RTCVideoEncoderFactory(); - - // cricket::WebRtcVideoEncoderFactory implementation. - virtual webrtc::VideoEncoder* CreateVideoEncoder( - webrtc::VideoCodecType type) OVERRIDE; - virtual void AddObserver(Observer* observer) OVERRIDE; - virtual void RemoveObserver(Observer* observer) OVERRIDE; - virtual const std::vector<VideoCodec>& codecs() const OVERRIDE; - virtual void DestroyVideoEncoder(webrtc::VideoEncoder* encoder) OVERRIDE; - - private: - const scoped_refptr<RendererGpuVideoAcceleratorFactories> gpu_factories_; - - // Codec support list of cricket::WebRtcVideoEncoderFactory::VideoCodec - // instances. - std::vector<VideoCodec> codecs_; - - DISALLOW_COPY_AND_ASSIGN(RTCVideoEncoderFactory); -}; - -} // namespace content - -#endif // CONTENT_RENDERER_MEDIA_RTC_VIDEO_ENCODER_FACTORY_H_ diff --git a/chromium/content/renderer/media/webmediaplayer_impl.cc b/chromium/content/renderer/media/webmediaplayer_impl.cc index d4780970eb4..227d0cf4b14 100644 --- a/chromium/content/renderer/media/webmediaplayer_impl.cc +++ b/chromium/content/renderer/media/webmediaplayer_impl.cc @@ -43,8 +43,8 @@ #include "media/filters/ffmpeg_audio_decoder.h" #include "media/filters/ffmpeg_demuxer.h" #include "media/filters/ffmpeg_video_decoder.h" -#include "media/filters/gpu_video_accelerator_factories.h" #include "media/filters/gpu_video_decoder.h" +#include "media/filters/gpu_video_decoder_factories.h" #include "media/filters/opus_audio_decoder.h" #include "media/filters/video_renderer_base.h" #include "media/filters/vpx_video_decoder.h" diff --git a/chromium/content/renderer/media/webmediaplayer_impl.h b/chromium/content/renderer/media/webmediaplayer_impl.h index c386b08f2b0..23b1ddf524a 100644 --- a/chromium/content/renderer/media/webmediaplayer_impl.h +++ b/chromium/content/renderer/media/webmediaplayer_impl.h @@ -56,7 +56,7 @@ class MessageLoopProxy; namespace media { class ChunkDemuxer; class FFmpegDemuxer; -class GpuVideoAcceleratorFactories; +class GpuVideoDecoderFactories; class MediaLog; } @@ -318,8 +318,8 @@ class WebMediaPlayerImpl bool incremented_externally_allocated_memory_; - // Factories for supporting video accelerators. May be null. - scoped_refptr<media::GpuVideoAcceleratorFactories> gpu_factories_; + // Factories for supporting GpuVideoDecoder. May be null. + scoped_refptr<media::GpuVideoDecoderFactories> gpu_factories_; // Routes audio playback to either AudioRendererSink or WebAudio. scoped_refptr<WebAudioSourceProviderImpl> audio_source_provider_; diff --git a/chromium/content/renderer/media/webmediaplayer_params.cc b/chromium/content/renderer/media/webmediaplayer_params.cc index a05abbfa571..04fe3105736 100644 --- a/chromium/content/renderer/media/webmediaplayer_params.cc +++ b/chromium/content/renderer/media/webmediaplayer_params.cc @@ -7,7 +7,7 @@ #include "base/message_loop/message_loop_proxy.h" #include "media/base/audio_renderer_sink.h" #include "media/base/media_log.h" -#include "media/filters/gpu_video_accelerator_factories.h" +#include "media/filters/gpu_video_decoder_factories.h" namespace content { @@ -15,7 +15,7 @@ WebMediaPlayerParams::WebMediaPlayerParams( const scoped_refptr<base::MessageLoopProxy>& message_loop_proxy, const base::Callback<void(const base::Closure&)>& defer_load_cb, const scoped_refptr<media::AudioRendererSink>& audio_renderer_sink, - const scoped_refptr<media::GpuVideoAcceleratorFactories>& gpu_factories, + const scoped_refptr<media::GpuVideoDecoderFactories>& gpu_factories, const scoped_refptr<media::MediaLog>& media_log) : message_loop_proxy_(message_loop_proxy), defer_load_cb_(defer_load_cb), diff --git a/chromium/content/renderer/media/webmediaplayer_params.h b/chromium/content/renderer/media/webmediaplayer_params.h index bf398642f77..4347a4af460 100644 --- a/chromium/content/renderer/media/webmediaplayer_params.h +++ b/chromium/content/renderer/media/webmediaplayer_params.h @@ -14,7 +14,7 @@ class MessageLoopProxy; namespace media { class AudioRendererSink; -class GpuVideoAcceleratorFactories; +class GpuVideoDecoderFactories; class MediaLog; } @@ -30,7 +30,7 @@ class WebMediaPlayerParams { const scoped_refptr<base::MessageLoopProxy>& message_loop_proxy, const base::Callback<void(const base::Closure&)>& defer_load_cb, const scoped_refptr<media::AudioRendererSink>& audio_renderer_sink, - const scoped_refptr<media::GpuVideoAcceleratorFactories>& gpu_factories, + const scoped_refptr<media::GpuVideoDecoderFactories>& gpu_factories, const scoped_refptr<media::MediaLog>& media_log); ~WebMediaPlayerParams(); @@ -46,8 +46,7 @@ class WebMediaPlayerParams { return audio_renderer_sink_; } - const scoped_refptr<media::GpuVideoAcceleratorFactories>& gpu_factories() - const { + const scoped_refptr<media::GpuVideoDecoderFactories>& gpu_factories() const { return gpu_factories_; } @@ -59,7 +58,7 @@ class WebMediaPlayerParams { scoped_refptr<base::MessageLoopProxy> message_loop_proxy_; base::Callback<void(const base::Closure&)> defer_load_cb_; scoped_refptr<media::AudioRendererSink> audio_renderer_sink_; - scoped_refptr<media::GpuVideoAcceleratorFactories> gpu_factories_; + scoped_refptr<media::GpuVideoDecoderFactories> gpu_factories_; scoped_refptr<media::MediaLog> media_log_; DISALLOW_IMPLICIT_CONSTRUCTORS(WebMediaPlayerParams); diff --git a/chromium/content/renderer/media/webrtc_audio_device_impl.cc b/chromium/content/renderer/media/webrtc_audio_device_impl.cc index c40e0a2219b..254561e4ae1 100644 --- a/chromium/content/renderer/media/webrtc_audio_device_impl.cc +++ b/chromium/content/renderer/media/webrtc_audio_device_impl.cc @@ -63,7 +63,9 @@ int WebRtcAudioDeviceImpl::CaptureData(const std::vector<int>& channels, int total_delay_ms = 0; { base::AutoLock auto_lock(lock_); - if (!recording_) + // Return immediately when not recording or |channels| is empty. + // See crbug.com/274017: renderer crash dereferencing invalid channels[0]. + if (!recording_ || channels.empty()) return 0; // Store the reported audio delay locally. diff --git a/chromium/content/renderer/media/webrtc_local_audio_track.cc b/chromium/content/renderer/media/webrtc_local_audio_track.cc index de86a3c4cc3..1aae3056f6d 100644 --- a/chromium/content/renderer/media/webrtc_local_audio_track.cc +++ b/chromium/content/renderer/media/webrtc_local_audio_track.cc @@ -34,6 +34,12 @@ WebRtcLocalAudioTrack::WebRtcLocalAudioTrack( // and APM (AudioProcessingModule) is turned on only for microphone data. DCHECK(capturer.get()); DVLOG(1) << "WebRtcLocalAudioTrack::WebRtcLocalAudioTrack()"; + + // TODO(tommi): Remove this, feed audio constraints to WebRtcLocalAudioTrack + // and check the constraints. This is here to fix a recent regression whereby + // audio processing is not enabled for WebAudio regardless of the hard coded + // audio constraints. For more info: http://crbug.com/277134 + need_audio_processing_ = true; } WebRtcLocalAudioTrack::~WebRtcLocalAudioTrack() { diff --git a/chromium/content/renderer/media/webrtc_local_audio_track_unittest.cc b/chromium/content/renderer/media/webrtc_local_audio_track_unittest.cc index 4720e45bf01..776cbb10035 100644 --- a/chromium/content/renderer/media/webrtc_local_audio_track_unittest.cc +++ b/chromium/content/renderer/media/webrtc_local_audio_track_unittest.cc @@ -175,7 +175,7 @@ TEST_F(WebRtcLocalAudioTrackTest, ConnectAndDisconnectOneSink) { EXPECT_CALL(*sink, SetCaptureFormat(_)).WillOnce(Return()); EXPECT_CALL(*sink, CaptureData( kNumberOfNetworkChannels, params.sample_rate(), params.channels(), - params.frames_per_buffer(), 0, 0, false)) + params.frames_per_buffer(), 0, 0, _)) .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event)); track->AddSink(sink.get()); @@ -245,7 +245,7 @@ TEST_F(WebRtcLocalAudioTrackTest, MultipleAudioTracks) { EXPECT_CALL(*sink_1, SetCaptureFormat(_)).WillOnce(Return()); EXPECT_CALL(*sink_1, CaptureData( 1, params.sample_rate(), params.channels(), - params.frames_per_buffer(), 0, 0, false)) + params.frames_per_buffer(), 0, 0, _)) .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event_1)); track_1->AddSink(sink_1.get()); EXPECT_TRUE(event_1.TimedWait(TestTimeouts::tiny_timeout())); @@ -266,11 +266,11 @@ TEST_F(WebRtcLocalAudioTrackTest, MultipleAudioTracks) { EXPECT_CALL(*sink_2, SetCaptureFormat(_)).WillOnce(Return()); EXPECT_CALL(*sink_1, CaptureData( 1, params.sample_rate(), params.channels(), - params.frames_per_buffer(), 0, 0, false)) + params.frames_per_buffer(), 0, 0, _)) .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event_1)); EXPECT_CALL(*sink_2, CaptureData( 1, params.sample_rate(), params.channels(), - params.frames_per_buffer(), 0, 0, false)) + params.frames_per_buffer(), 0, 0, _)) .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event_2)); track_2->AddSink(sink_2.get()); EXPECT_TRUE(event_1.TimedWait(TestTimeouts::tiny_timeout())); @@ -319,7 +319,7 @@ TEST_F(WebRtcLocalAudioTrackTest, StartAndStopAudioTracks) { scoped_ptr<MockWebRtcAudioCapturerSink> sink( new MockWebRtcAudioCapturerSink()); event.Reset(); - EXPECT_CALL(*sink, CaptureData(_, _, _, _, 0, 0, false)) + EXPECT_CALL(*sink, CaptureData(_, _, _, _, 0, 0, _)) .Times(AnyNumber()).WillRepeatedly(Return()); EXPECT_CALL(*sink, SetCaptureFormat(_)).Times(1); track_1->AddSink(sink.get()); @@ -397,7 +397,7 @@ TEST_F(WebRtcLocalAudioTrackTest, ConnectTracksToDifferentCapturers) { scoped_ptr<MockWebRtcAudioCapturerSink> sink_1( new MockWebRtcAudioCapturerSink()); EXPECT_CALL(*sink_1.get(), CaptureData(kNumberOfNetworkChannelsForTrack1, - 48000, 2, _, 0, 0, false)) + 48000, 2, _, 0, 0, _)) .Times(AnyNumber()).WillRepeatedly(Return()); EXPECT_CALL(*sink_1.get(), SetCaptureFormat(_)).Times(1); track_1->AddSink(sink_1.get()); diff --git a/chromium/content/renderer/pepper/pepper_in_process_router.cc b/chromium/content/renderer/pepper/pepper_in_process_router.cc index d5c0d429a40..1446426dd77 100644 --- a/chromium/content/renderer/pepper/pepper_in_process_router.cc +++ b/chromium/content/renderer/pepper/pepper_in_process_router.cc @@ -110,9 +110,24 @@ bool PepperInProcessRouter::SendToHost(IPC::Message* msg) { scoped_ptr<IPC::Message> message(msg); if (!message->is_sync()) { - bool result = host_impl_->GetPpapiHost()->OnMessageReceived(*message); - DCHECK(result) << "The message was not handled by the host."; - return true; + // If this is a resource destroyed message, post a task to dispatch it. + // Dispatching it synchronously can cause the host to re-enter the proxy + // code while we're still in the resource destructor, leading to a crash. + // http://crbug.com/276368. + // This won't cause message reordering problems because the resource + // destroyed message is always the last one sent for a resource. + if (message->type() == PpapiHostMsg_ResourceDestroyed::ID) { + base::MessageLoop::current()->PostTask( + FROM_HERE, + base::Bind(&PepperInProcessRouter::DispatchHostMsg, + weak_factory_.GetWeakPtr(), + base::Owned(message.release()))); + return true; + } else { + bool result = host_impl_->GetPpapiHost()->OnMessageReceived(*message); + DCHECK(result) << "The message was not handled by the host."; + return true; + } } pending_message_id_ = IPC::SyncMessage::GetMessageId(*message); @@ -146,6 +161,11 @@ bool PepperInProcessRouter::SendToPlugin(IPC::Message* msg) { return true; } +void PepperInProcessRouter::DispatchHostMsg(IPC::Message* msg) { + bool handled = host_impl_->GetPpapiHost()->OnMessageReceived(*msg); + DCHECK(handled); +} + void PepperInProcessRouter::DispatchPluginMsg(IPC::Message* msg) { bool handled = OnPluginMsgReceived(*msg); DCHECK(handled); diff --git a/chromium/content/renderer/pepper/pepper_in_process_router.h b/chromium/content/renderer/pepper/pepper_in_process_router.h index 568c18eaab4..77b19881174 100644 --- a/chromium/content/renderer/pepper/pepper_in_process_router.h +++ b/chromium/content/renderer/pepper/pepper_in_process_router.h @@ -71,6 +71,7 @@ class PepperInProcessRouter { private: bool SendToHost(IPC::Message *msg); bool SendToPlugin(IPC::Message *msg); + void DispatchHostMsg(IPC::Message* msg); void DispatchPluginMsg(IPC::Message* msg); bool SendToBrowser(IPC::Message *msg); diff --git a/chromium/content/renderer/pepper/pepper_url_loader_host.cc b/chromium/content/renderer/pepper/pepper_url_loader_host.cc index 8343f1934ea..9b951f57354 100644 --- a/chromium/content/renderer/pepper/pepper_url_loader_host.cc +++ b/chromium/content/renderer/pepper/pepper_url_loader_host.cc @@ -249,9 +249,12 @@ int32_t PepperURLLoaderHost::InternalOnHostMsgOpen( WebFrame* frame = GetFrame(); if (!frame) return PP_ERROR_FAILED; + WebURLRequest web_request; if (!CreateWebURLRequest(&filled_in_request_data, frame, &web_request)) return PP_ERROR_FAILED; + + web_request.setTargetType(WebURLRequest::TargetIsObject); web_request.setRequestorProcessID(renderer_ppapi_host_->GetPluginPID()); WebURLLoaderOptions options; diff --git a/chromium/content/renderer/pepper/url_request_info_util.cc b/chromium/content/renderer/pepper/url_request_info_util.cc index e82c8a18612..72365fde336 100644 --- a/chromium/content/renderer/pepper/url_request_info_util.cc +++ b/chromium/content/renderer/pepper/url_request_info_util.cc @@ -124,7 +124,6 @@ bool CreateWebURLRequest(ppapi::URLRequestInfoData* data, return false; dest->initialize(); - dest->setTargetType(WebURLRequest::TargetIsObject); dest->setURL(frame->document().completeURL(WebString::fromUTF8( data->url))); dest->setDownloadToFile(data->stream_to_file); diff --git a/chromium/content/renderer/render_frame_impl.cc b/chromium/content/renderer/render_frame_impl.cc index 92bfb3d6a3c..fff52e0ff96 100644 --- a/chromium/content/renderer/render_frame_impl.cc +++ b/chromium/content/renderer/render_frame_impl.cc @@ -274,6 +274,17 @@ void RenderFrameImpl::loadURLExternally( WebKit::WebNavigationPolicy RenderFrameImpl::decidePolicyForNavigation( WebKit::WebFrame* frame, + WebKit::WebDataSource::ExtraData* extra_data, + const WebKit::WebURLRequest& request, + WebKit::WebNavigationType type, + WebKit::WebNavigationPolicy default_policy, + bool is_redirect) { + return render_view_->decidePolicyForNavigation( + frame, extra_data, request, type, default_policy, is_redirect); +} + +WebKit::WebNavigationPolicy RenderFrameImpl::decidePolicyForNavigation( + WebKit::WebFrame* frame, const WebKit::WebURLRequest& request, WebKit::WebNavigationType type, WebKit::WebNavigationPolicy default_policy, diff --git a/chromium/content/renderer/render_frame_impl.h b/chromium/content/renderer/render_frame_impl.h index f4686b2d15d..f64a5230455 100644 --- a/chromium/content/renderer/render_frame_impl.h +++ b/chromium/content/renderer/render_frame_impl.h @@ -71,6 +71,14 @@ class CONTENT_EXPORT RenderFrameImpl const WebKit::WebString& suggested_name); virtual WebKit::WebNavigationPolicy decidePolicyForNavigation( WebKit::WebFrame* frame, + WebKit::WebDataSource::ExtraData* extra_data, + const WebKit::WebURLRequest& request, + WebKit::WebNavigationType type, + WebKit::WebNavigationPolicy default_policy, + bool is_redirect); + // DEPRECATED + virtual WebKit::WebNavigationPolicy decidePolicyForNavigation( + WebKit::WebFrame* frame, const WebKit::WebURLRequest& request, WebKit::WebNavigationType type, WebKit::WebNavigationPolicy default_policy, diff --git a/chromium/content/renderer/render_thread_impl.cc b/chromium/content/renderer/render_thread_impl.cc index f15738dd00a..b1e4a71cd6f 100644 --- a/chromium/content/renderer/render_thread_impl.cc +++ b/chromium/content/renderer/render_thread_impl.cc @@ -87,7 +87,7 @@ #include "ipc/ipc_platform_file.h" #include "media/base/audio_hardware_config.h" #include "media/base/media.h" -#include "media/filters/gpu_video_accelerator_factories.h" +#include "media/filters/gpu_video_decoder_factories.h" #include "net/base/net_errors.h" #include "net/base/net_util.h" #include "third_party/WebKit/public/platform/WebString.h" @@ -887,20 +887,22 @@ void RenderThreadImpl::PostponeIdleNotification() { idle_notifications_to_skip_ = 2; } -scoped_refptr<RendererGpuVideoAcceleratorFactories> +scoped_refptr<RendererGpuVideoDecoderFactories> RenderThreadImpl::GetGpuFactories( const scoped_refptr<base::MessageLoopProxy>& factories_loop) { DCHECK(IsMainThread()); const CommandLine* cmd_line = CommandLine::ForCurrentProcess(); - scoped_refptr<RendererGpuVideoAcceleratorFactories> gpu_factories; + scoped_refptr<RendererGpuVideoDecoderFactories> gpu_factories; WebGraphicsContext3DCommandBufferImpl* context3d = NULL; if (!cmd_line->HasSwitch(switches::kDisableAcceleratedVideoDecode)) context3d = GetGpuVDAContext3D(); - GpuChannelHost* gpu_channel_host = GetGpuChannel(); - if (gpu_channel_host) { - gpu_factories = new RendererGpuVideoAcceleratorFactories( - gpu_channel_host, factories_loop, context3d); + if (context3d) { + GpuChannelHost* gpu_channel_host = GetGpuChannel(); + if (gpu_channel_host) { + gpu_factories = new RendererGpuVideoDecoderFactories( + gpu_channel_host, factories_loop, context3d); + } } return gpu_factories; } diff --git a/chromium/content/renderer/render_thread_impl.h b/chromium/content/renderer/render_thread_impl.h index d11a4989557..fd2cfff7f42 100644 --- a/chromium/content/renderer/render_thread_impl.h +++ b/chromium/content/renderer/render_thread_impl.h @@ -19,7 +19,7 @@ #include "content/common/gpu/client/gpu_channel_host.h" #include "content/common/gpu/gpu_process_launch_causes.h" #include "content/public/renderer/render_thread.h" -#include "content/renderer/media/renderer_gpu_video_accelerator_factories.h" +#include "content/renderer/media/renderer_gpu_video_decoder_factories.h" #include "ipc/ipc_channel_proxy.h" #include "ui/gfx/native_widget_types.h" @@ -55,6 +55,7 @@ class ForwardingMessageFilter; namespace media { class AudioHardwareConfig; +class GpuVideoDecoderFactories; } namespace v8 { @@ -257,8 +258,9 @@ class CONTENT_EXPORT RenderThreadImpl : public RenderThread, // not sent for at least one notification delay. void PostponeIdleNotification(); - // Gets gpu factories, which will run on |factories_loop|. - scoped_refptr<RendererGpuVideoAcceleratorFactories> GetGpuFactories( + // Gets gpu factories, which will run on |factories_loop|. Returns NULL if VDA + // is disabled or a graphics context cannot be obtained. + scoped_refptr<RendererGpuVideoDecoderFactories> GetGpuFactories( const scoped_refptr<base::MessageLoopProxy>& factories_loop); // Returns a graphics context shared among all diff --git a/chromium/content/renderer/render_view_browsertest.cc b/chromium/content/renderer/render_view_browsertest.cc index 125f4c3214d..c400a749677 100644 --- a/chromium/content/renderer/render_view_browsertest.cc +++ b/chromium/content/renderer/render_view_browsertest.cc @@ -771,7 +771,10 @@ TEST_F(RenderViewImplTest, DontIgnoreBackAfterNavEntryLimit) { // Test that our IME backend sends a notification message when the input focus // changes. -TEST_F(RenderViewImplTest, OnImeTypeChanged) { +// crbug.com/276821: +// Because Blink change cause this test failed, we first disabled this test and +// fix later. +TEST_F(RenderViewImplTest, DISABLED_OnImeTypeChanged) { // Enable our IME backend code. view()->OnSetInputMethodActive(true); diff --git a/chromium/content/renderer/render_view_impl.cc b/chromium/content/renderer/render_view_impl.cc index d64150c58ab..1df467e88f2 100644 --- a/chromium/content/renderer/render_view_impl.cc +++ b/chromium/content/renderer/render_view_impl.cc @@ -132,7 +132,7 @@ #include "media/base/filter_collection.h" #include "media/base/media_switches.h" #include "media/filters/audio_renderer_impl.h" -#include "media/filters/gpu_video_accelerator_factories.h" +#include "media/filters/gpu_video_decoder_factories.h" #include "net/base/data_url.h" #include "net/base/escape.h" #include "net/base/net_errors.h" @@ -2290,6 +2290,7 @@ WebView* RenderViewImpl::createView( params.frame_name = frame_name; params.opener_frame_id = creator->identifier(); params.opener_url = creator->document().url(); + params.opener_top_level_frame_url = creator->top()->document().url(); GURL security_url(creator->document().securityOrigin().toString().utf8()); if (!security_url.is_valid()) security_url = GURL(); @@ -2687,10 +2688,6 @@ void RenderViewImpl::showContextMenu( RenderViewObserver, observers_, DidRequestShowContextMenu(frame, data)); } -void RenderViewImpl::clearContextMenu() { - context_menu_node_.reset(); -} - void RenderViewImpl::setStatusText(const WebString& text) { } @@ -2993,7 +2990,7 @@ WebMediaPlayer* RenderViewImpl::createMediaPlayer( #if defined(ENABLE_WEBRTC) EnsureMediaStreamClient(); #if !defined(GOOGLE_TV) - if (media_stream_client_->IsMediaStream(url)) { + if (media_stream_client_ && media_stream_client_->IsMediaStream(url)) { #if defined(OS_ANDROID) && defined(ARCH_CPU_ARMEL) bool found_neon = (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0; @@ -3071,7 +3068,7 @@ WebMediaPlayer* RenderViewImpl::createMediaPlayer( DVLOG(1) << "Using AudioRendererMixerManager-provided sink: " << sink.get(); } - scoped_refptr<media::GpuVideoAcceleratorFactories> gpu_factories = + scoped_refptr<media::GpuVideoDecoderFactories> gpu_factories = RenderThreadImpl::current()->GetGpuFactories( RenderThreadImpl::current()->GetMediaThreadMessageLoopProxy()); @@ -4235,13 +4232,17 @@ bool RenderViewImpl::ShouldUpdateSelectionTextFromContextMenuParams( void RenderViewImpl::reportFindInPageMatchCount(int request_id, int count, bool final_update) { - NOTREACHED(); + // TODO(jam): switch PepperPluginInstanceImpl to take a RenderFrame + main_render_frame_->reportFindInPageMatchCount( + request_id, count, final_update); } void RenderViewImpl::reportFindInPageSelection(int request_id, int active_match_ordinal, const WebRect& selection_rect) { - NOTREACHED(); + // TODO(jam): switch PepperPluginInstanceImpl to take a RenderFrame + main_render_frame_->reportFindInPageSelection( + request_id, active_match_ordinal, selection_rect); } void RenderViewImpl::openFileSystem( diff --git a/chromium/content/renderer/render_view_impl.h b/chromium/content/renderer/render_view_impl.h index d338b172a7e..4c6d77acb36 100644 --- a/chromium/content/renderer/render_view_impl.h +++ b/chromium/content/renderer/render_view_impl.h @@ -484,7 +484,6 @@ class CONTENT_EXPORT RenderViewImpl const WebKit::WebString& message); virtual void showContextMenu(WebKit::WebFrame* frame, const WebKit::WebContextMenuData& data); - virtual void clearContextMenu(); virtual void setStatusText(const WebKit::WebString& text); virtual void setMouseOverURL(const WebKit::WebURL& url); virtual void setKeyboardFocusURL(const WebKit::WebURL& url); @@ -1091,6 +1090,9 @@ class CONTENT_EXPORT RenderViewImpl void CheckPreferredSize(); // Initializes |media_stream_client_| if needed. + // TODO(qinmin): rename this function as it does not guarantee + // |media_stream_client_| will be created. + // http://crbug.com/278490. void EnsureMediaStreamClient(); // This callback is triggered when DownloadFavicon completes, either diff --git a/chromium/content/renderer/renderer_main.cc b/chromium/content/renderer/renderer_main.cc index 5fe9a9a2176..0a8b0d84bfc 100644 --- a/chromium/content/renderer/renderer_main.cc +++ b/chromium/content/renderer/renderer_main.cc @@ -181,6 +181,8 @@ int RendererMain(const MainFunctionParams& parameters) { base::FieldTrialList field_trial_list(NULL); // Ensure any field trials in browser are reflected into renderer. if (parsed_command_line.HasSwitch(switches::kForceFieldTrials)) { + std::string persistent = parsed_command_line.GetSwitchValueASCII( + switches::kForceFieldTrials); // Field trials are created in an "activated" state to ensure they get // reported in crash reports. bool result = base::FieldTrialList::CreateTrialsFromString( diff --git a/chromium/content/renderer/renderer_webkitplatformsupport_impl.cc b/chromium/content/renderer/renderer_webkitplatformsupport_impl.cc index fd07f28ce95..d5156a1d350 100644 --- a/chromium/content/renderer/renderer_webkitplatformsupport_impl.cc +++ b/chromium/content/renderer/renderer_webkitplatformsupport_impl.cc @@ -148,6 +148,8 @@ class RendererWebKitPlatformSupportImpl::MimeRegistry const WebKit::WebString& file_extension); virtual WebKit::WebString mimeTypeFromFile( const WebKit::WebString& file_path); + virtual WebKit::WebString preferredExtensionForMIMEType( + const WebKit::WebString& mime_type); }; class RendererWebKitPlatformSupportImpl::FileUtilities @@ -223,10 +225,6 @@ RendererWebKitPlatformSupportImpl::RendererWebKitPlatformSupportImpl() } RendererWebKitPlatformSupportImpl::~RendererWebKitPlatformSupportImpl() { -#ifdef USE_THREADLOCAL_WEBFILESYSTEM - // TODO(kinuko): Delete this ifdef after blink side switch's over. - WebFileSystemImpl::DeleteThreadSpecificInstance(); -#endif } //------------------------------------------------------------------------------ @@ -376,14 +374,9 @@ WebIDBFactory* RendererWebKitPlatformSupportImpl::idbFactory() { //------------------------------------------------------------------------------ WebFileSystem* RendererWebKitPlatformSupportImpl::fileSystem() { -#ifdef USE_THREADLOCAL_WEBFILESYSTEM - // TODO(kinuko): Delete this ifdef after blink side switch's over. - return WebFileSystemImpl::ThreadSpecificInstance(child_thread_loop_.get()); -#else if (!web_file_system_) web_file_system_.reset(new WebFileSystemImpl(child_thread_loop_.get())); return web_file_system_.get(); -#endif } //------------------------------------------------------------------------------ @@ -491,6 +484,21 @@ WebString RendererWebKitPlatformSupportImpl::MimeRegistry::mimeTypeFromFile( return ASCIIToUTF16(mime_type); } +WebString +RendererWebKitPlatformSupportImpl::MimeRegistry::preferredExtensionForMIMEType( + const WebString& mime_type) { + if (IsPluginProcess()) + return SimpleWebMimeRegistryImpl::preferredExtensionForMIMEType(mime_type); + + // The sandbox restricts our access to the registry, so we need to proxy + // these calls over to the browser process. + base::FilePath::StringType file_extension; + RenderThread::Get()->Send( + new MimeRegistryMsg_GetPreferredExtensionForMimeType( + UTF16ToASCII(mime_type), &file_extension)); + return base::FilePath(file_extension).AsUTF16Unsafe(); +} + //------------------------------------------------------------------------------ bool RendererWebKitPlatformSupportImpl::FileUtilities::getFileInfo( diff --git a/chromium/content/renderer/rendering_benchmark.cc b/chromium/content/renderer/rendering_benchmark.cc new file mode 100644 index 00000000000..5415bdd7d8f --- /dev/null +++ b/chromium/content/renderer/rendering_benchmark.cc @@ -0,0 +1,12 @@ +// 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/renderer/rendering_benchmark.h" + +namespace content { + +RenderingBenchmark::RenderingBenchmark(const std::string& name) : name_(name) {} +RenderingBenchmark::~RenderingBenchmark() {} + +} // namespace content diff --git a/chromium/content/renderer/rendering_benchmark.h b/chromium/content/renderer/rendering_benchmark.h new file mode 100644 index 00000000000..44b5a84d79a --- /dev/null +++ b/chromium/content/renderer/rendering_benchmark.h @@ -0,0 +1,39 @@ +// 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_RENDERER_RENDERING_BENCHMARK_H_ +#define CONTENT_RENDERER_RENDERING_BENCHMARK_H_ + +#include <string> + +#include "base/basictypes.h" + +namespace WebKit { +class WebViewBenchmarkSupport; +} + +namespace content { +class RenderingBenchmarkResults; + +class RenderingBenchmark { + public: + explicit RenderingBenchmark(const std::string& name); + virtual ~RenderingBenchmark(); + + virtual void SetUp(WebKit::WebViewBenchmarkSupport* benchmarkSupport) {} + + virtual double Run(WebKit::WebViewBenchmarkSupport* benchmarkSupport) = 0; + + virtual void TearDown(WebKit::WebViewBenchmarkSupport* benchmarkSupport) {} + + const std::string& name() { return name_; } + + private: + const std::string name_; + + DISALLOW_COPY_AND_ASSIGN(RenderingBenchmark); +}; +} // namespace content + +#endif // CONTENT_RENDERER_RENDERING_BENCHMARK_H_ diff --git a/chromium/content/shell/shell.cc b/chromium/content/shell/shell.cc index 93f13bf94d4..0fadcf8d416 100644 --- a/chromium/content/shell/shell.cc +++ b/chromium/content/shell/shell.cc @@ -306,7 +306,7 @@ void Shell::WebContentsCreated(WebContents* source_contents, } void Shell::DidNavigateMainFramePostCommit(WebContents* web_contents) { - PlatformSetAddressBarURL(web_contents->GetLastCommittedURL()); + PlatformSetAddressBarURL(web_contents->GetURL()); } JavaScriptDialogManager* Shell::GetJavaScriptDialogManager() { diff --git a/chromium/content/worker/worker_webkitplatformsupport_impl.cc b/chromium/content/worker/worker_webkitplatformsupport_impl.cc index d1aacef60bf..144db959a3d 100644 --- a/chromium/content/worker/worker_webkitplatformsupport_impl.cc +++ b/chromium/content/worker/worker_webkitplatformsupport_impl.cc @@ -86,10 +86,6 @@ WorkerWebKitPlatformSupportImpl::WorkerWebKitPlatformSupportImpl( } WorkerWebKitPlatformSupportImpl::~WorkerWebKitPlatformSupportImpl() { -#ifdef USE_THREADLOCAL_WEBFILESYSTEM - // TODO(kinuko): Delete this ifdef after blink side switch's over. - WebFileSystemImpl::DeleteThreadSpecificInstance(); -#endif } WebClipboard* WorkerWebKitPlatformSupportImpl::clipboard() { @@ -102,14 +98,9 @@ WebMimeRegistry* WorkerWebKitPlatformSupportImpl::mimeRegistry() { } WebFileSystem* WorkerWebKitPlatformSupportImpl::fileSystem() { -#ifdef USE_THREADLOCAL_WEBFILESYSTEM - // TODO(kinuko): Delete this ifdef after blink side switch's over. - return WebFileSystemImpl::ThreadSpecificInstance(child_thread_loop_.get()); -#else if (!web_file_system_) web_file_system_.reset(new WebFileSystemImpl(child_thread_loop_.get())); return web_file_system_.get(); -#endif } WebFileUtilities* WorkerWebKitPlatformSupportImpl::fileUtilities() { @@ -291,6 +282,15 @@ WebString WorkerWebKitPlatformSupportImpl::mimeTypeFromFile( return ASCIIToUTF16(mime_type); } +WebString WorkerWebKitPlatformSupportImpl::preferredExtensionForMIMEType( + const WebString& mime_type) { + base::FilePath::StringType file_extension; + thread_safe_sender_->Send( + new MimeRegistryMsg_GetPreferredExtensionForMimeType( + UTF16ToASCII(mime_type), &file_extension)); + return base::FilePath(file_extension).AsUTF16Unsafe(); +} + WebBlobRegistry* WorkerWebKitPlatformSupportImpl::blobRegistry() { if (!blob_registry_.get() && thread_safe_sender_.get()) blob_registry_.reset(new WebBlobRegistryImpl(thread_safe_sender_.get())); diff --git a/chromium/content/worker/worker_webkitplatformsupport_impl.h b/chromium/content/worker/worker_webkitplatformsupport_impl.h index d429822a57f..a85d574ec0c 100644 --- a/chromium/content/worker/worker_webkitplatformsupport_impl.h +++ b/chromium/content/worker/worker_webkitplatformsupport_impl.h @@ -98,6 +98,8 @@ class WorkerWebKitPlatformSupportImpl : public WebKitPlatformSupportImpl, virtual WebKit::WebString wellKnownMimeTypeForExtension( const WebKit::WebString&); virtual WebKit::WebString mimeTypeFromFile(const WebKit::WebString&); + virtual WebKit::WebString preferredExtensionForMIMEType( + const WebKit::WebString&); virtual void queryStorageUsageAndQuota( const WebKit::WebURL& storage_partition, WebKit::WebStorageQuotaType, diff --git a/chromium/content/zygote/zygote_linux.cc b/chromium/content/zygote/zygote_linux.cc index 6e42a9d045a..abb52aea32c 100644 --- a/chromium/content/zygote/zygote_linux.cc +++ b/chromium/content/zygote/zygote_linux.cc @@ -326,14 +326,10 @@ int Zygote::ForkWithRealPid(const std::string& process_type, LOG(ERROR) << "METHOD_GET_CHILD_WITH_INODE failed"; goto error; } - real_pids_to_sandbox_pids[real_pid] = pid; - } else { - // If no SUID sandbox is involved then no pid translation is - // necessary. - real_pid = pid; } if (use_helper) { + real_pid = pid; if (!helper_->AckChild(pipe_fds[1], channel_switch)) { LOG(ERROR) << "Failed to synchronise with zygote fork helper"; goto error; |