summaryrefslogtreecommitdiff
path: root/content/browser
diff options
context:
space:
mode:
authorTorne (Richard Coles) <torne@google.com>2013-08-05 13:57:33 +0100
committerTorne (Richard Coles) <torne@google.com>2013-08-05 13:57:33 +0100
commita36e5920737c6adbddd3e43b760e5de8431db6e0 (patch)
tree347d048bb8c8828d50113bf94ace40bf0613f2cd /content/browser
parent34378da0e9429d394aafdaa771301aff58447cb1 (diff)
downloadchromium_org-a36e5920737c6adbddd3e43b760e5de8431db6e0.tar.gz
Merge from Chromium at DEPS revision r215573
This commit was generated by merge_to_master.py. Change-Id: Ib95814f98e5765b459dd32425f9bf9138edf2bca
Diffstat (limited to 'content/browser')
-rw-r--r--content/browser/DEPS5
-rw-r--r--content/browser/accessibility/browser_accessibility_gtk.cc274
-rw-r--r--content/browser/accessibility/browser_accessibility_gtk.h1
-rw-r--r--content/browser/android/DEPS3
-rw-r--r--content/browser/android/browser_jni_registrar.cc63
-rw-r--r--content/browser/android/browser_media_player_manager.cc18
-rw-r--r--content/browser/android/browser_media_player_manager.h1
-rw-r--r--content/browser/android/browser_startup_config.cc25
-rw-r--r--content/browser/android/browser_startup_config.h18
-rw-r--r--content/browser/android/content_video_view.cc19
-rw-r--r--content/browser/android/content_video_view.h4
-rw-r--r--content/browser/android/content_view_core_impl.cc8
-rw-r--r--content/browser/android/content_view_core_impl.h1
-rw-r--r--content/browser/android/edge_effect.cc8
-rw-r--r--content/browser/android/in_process/synchronous_compositor_output_surface.cc11
-rw-r--r--content/browser/android/overscroll_glow.cc24
-rw-r--r--content/browser/aura/OWNERS1
-rw-r--r--content/browser/aura/gpu_process_transport_factory.cc26
-rw-r--r--content/browser/aura/software_output_device_win.cc (renamed from content/browser/renderer_host/software_output_device_win.cc)4
-rw-r--r--content/browser/aura/software_output_device_win.h (renamed from content/browser/renderer_host/software_output_device_win.h)8
-rw-r--r--content/browser/aura/software_output_device_x11.cc (renamed from content/browser/renderer_host/software_output_device_x11.cc)4
-rw-r--r--content/browser/aura/software_output_device_x11.h (renamed from content/browser/renderer_host/software_output_device_x11.h)8
-rw-r--r--content/browser/browser_child_process_host_impl.cc3
-rw-r--r--content/browser/browser_child_process_host_impl.h3
-rw-r--r--content/browser/browser_main_loop.cc78
-rw-r--r--content/browser/browser_main_loop.h18
-rw-r--r--content/browser/browser_main_runner.cc15
-rw-r--r--content/browser/browser_plugin/browser_plugin_guest.cc11
-rw-r--r--content/browser/browser_plugin/browser_plugin_guest.h5
-rw-r--r--content/browser/byte_stream.cc37
-rw-r--r--content/browser/byte_stream.h25
-rw-r--r--content/browser/byte_stream_unittest.cc69
-rw-r--r--content/browser/device_orientation/data_fetcher_shared_memory.h14
-rw-r--r--content/browser/device_orientation/data_fetcher_shared_memory_android.cc8
-rw-r--r--content/browser/device_orientation/data_fetcher_shared_memory_default.cc6
-rw-r--r--content/browser/device_orientation/device_motion_provider.cc131
-rw-r--r--content/browser/device_orientation/device_motion_provider.h19
-rw-r--r--content/browser/device_orientation/device_motion_provider_unittest.cc98
-rw-r--r--content/browser/device_orientation/motion.cc66
-rw-r--r--content/browser/device_orientation/motion.h165
-rw-r--r--content/browser/device_orientation/motion_message_filter.cc32
-rw-r--r--content/browser/device_orientation/motion_message_filter.h30
-rw-r--r--content/browser/device_orientation/observer_delegate.cc4
-rw-r--r--content/browser/device_orientation/provider_unittest.cc124
-rw-r--r--content/browser/devtools/devtools_http_handler_impl.cc4
-rw-r--r--content/browser/download/download_file_impl.cc3
-rw-r--r--content/browser/download/download_file_unittest.cc2
-rw-r--r--content/browser/download/download_item_impl.cc2
-rw-r--r--content/browser/download/download_item_impl_unittest.cc2
-rw-r--r--content/browser/download/download_manager_impl.cc1
-rw-r--r--content/browser/download/download_resource_handler.cc7
-rw-r--r--content/browser/download/download_resource_handler.h1
-rw-r--r--content/browser/download/download_stats.cc7
-rw-r--r--content/browser/download/download_stats.h22
-rw-r--r--content/browser/download/save_package.cc2
-rw-r--r--content/browser/fileapi/browser_file_system_helper.cc11
-rw-r--r--content/browser/fileapi/fileapi_message_filter.cc7
-rw-r--r--content/browser/gpu/compositor_util.cc2
-rw-r--r--content/browser/gpu/gpu_data_manager_impl_private.cc40
-rw-r--r--content/browser/gpu/gpu_data_manager_impl_private.h2
-rw-r--r--content/browser/gpu/gpu_internals_ui.cc8
-rw-r--r--content/browser/gpu/gpu_process_host.cc1
-rw-r--r--content/browser/gpu/shader_disk_cache.cc5
-rw-r--r--content/browser/gpu/shader_disk_cache.h4
-rw-r--r--content/browser/gpu/test_support_gpu.gypi1
-rw-r--r--content/browser/gpu/webgl_conformance_test.cc1
-rw-r--r--content/browser/hyphenator/hyphenator_message_filter.cc120
-rw-r--r--content/browser/hyphenator/hyphenator_message_filter.h75
-rw-r--r--content/browser/hyphenator/hyphenator_message_filter_unittest.cc154
-rw-r--r--content/browser/media/encrypted_media_browsertest.cc3
-rw-r--r--content/browser/media/webrtc_browsertest.cc52
-rw-r--r--content/browser/power_monitor_message_broadcaster.cc39
-rw-r--r--content/browser/power_monitor_message_broadcaster.h41
-rw-r--r--content/browser/power_monitor_message_broadcaster_unittest.cc109
-rw-r--r--content/browser/renderer_host/DEPS3
-rw-r--r--content/browser/renderer_host/compositor_impl_android.cc3
-rw-r--r--content/browser/renderer_host/compositor_impl_android.h3
-rw-r--r--content/browser/renderer_host/file_utilities_message_filter.cc38
-rw-r--r--content/browser/renderer_host/file_utilities_message_filter.h3
-rw-r--r--content/browser/renderer_host/input/touch_event_queue.cc5
-rw-r--r--content/browser/renderer_host/java/DEPS1
-rw-r--r--content/browser/renderer_host/media/audio_input_renderer_host.cc17
-rw-r--r--content/browser/renderer_host/media/media_stream_manager.cc12
-rw-r--r--content/browser/renderer_host/media/midi_dispatcher_host.cc68
-rw-r--r--content/browser/renderer_host/media/midi_dispatcher_host.h48
-rw-r--r--content/browser/renderer_host/media/midi_host.cc79
-rw-r--r--content/browser/renderer_host/media/midi_host.h17
-rw-r--r--content/browser/renderer_host/media/screen_capture_device.cc11
-rw-r--r--content/browser/renderer_host/media/screen_capture_device.h5
-rw-r--r--content/browser/renderer_host/media/screen_capture_device_unittest.cc21
-rw-r--r--content/browser/renderer_host/media/video_capture_controller.cc8
-rw-r--r--content/browser/renderer_host/media/video_capture_controller_event_handler.h8
-rw-r--r--content/browser/renderer_host/media/video_capture_controller_unittest.cc21
-rw-r--r--content/browser/renderer_host/media/video_capture_host.cc31
-rw-r--r--content/browser/renderer_host/media/video_capture_host.h20
-rw-r--r--content/browser/renderer_host/media/video_capture_manager.cc17
-rw-r--r--content/browser/renderer_host/media/web_contents_video_capture_device.cc13
-rw-r--r--content/browser/renderer_host/media/web_contents_video_capture_device.h6
-rw-r--r--content/browser/renderer_host/media/web_contents_video_capture_device_unittest.cc89
-rw-r--r--content/browser/renderer_host/pepper/pepper_file_ref_host.cc13
-rw-r--r--content/browser/renderer_host/pepper/pepper_file_ref_host.h2
-rw-r--r--content/browser/renderer_host/pepper/pepper_file_system_browser_host.cc5
-rw-r--r--content/browser/renderer_host/pepper/pepper_file_system_browser_host.h2
-rw-r--r--content/browser/renderer_host/pepper/pepper_flash_file_message_filter.cc66
-rw-r--r--content/browser/renderer_host/pepper/pepper_flash_file_message_filter.h8
-rw-r--r--content/browser/renderer_host/pepper/pepper_internal_file_ref_backend.h2
-rw-r--r--content/browser/renderer_host/pepper/pepper_renderer_connection.cc93
-rw-r--r--content/browser/renderer_host/pepper/pepper_renderer_connection.h29
-rw-r--r--content/browser/renderer_host/pepper/pepper_security_helper.cc54
-rw-r--r--content/browser/renderer_host/pepper/pepper_security_helper.h21
-rw-r--r--content/browser/renderer_host/render_message_filter.cc44
-rw-r--r--content/browser/renderer_host/render_message_filter.h16
-rw-r--r--content/browser/renderer_host/render_process_host_impl.cc17
-rw-r--r--content/browser/renderer_host/render_process_host_impl.h4
-rw-r--r--content/browser/renderer_host/render_sandbox_host_linux.cc42
-rw-r--r--content/browser/renderer_host/render_widget_host_impl.cc16
-rw-r--r--content/browser/renderer_host/render_widget_host_view_android.cc31
-rw-r--r--content/browser/renderer_host/render_widget_host_view_android.h4
-rw-r--r--content/browser/renderer_host/render_widget_host_view_aura.cc72
-rw-r--r--content/browser/renderer_host/render_widget_host_view_aura.h9
-rw-r--r--content/browser/renderer_host/render_widget_host_view_base.cc39
-rw-r--r--content/browser/renderer_host/render_widget_host_view_base.h3
-rw-r--r--content/browser/renderer_host/render_widget_host_view_browsertest.cc20
-rw-r--r--content/browser/renderer_host/render_widget_host_view_mac.h7
-rw-r--r--content/browser/renderer_host/render_widget_host_view_mac.mm64
-rw-r--r--content/browser/renderer_host/render_widget_host_view_win.cc43
-rw-r--r--content/browser/renderer_host/ui_events_helper.cc6
-rw-r--r--content/browser/resources/media/new/integration_test.html86
-rw-r--r--content/browser/resources/media/new/main.js134
-rw-r--r--content/browser/resources/media/new/util.js34
-rw-r--r--content/browser/ssl/ssl_host_state.cc17
-rw-r--r--content/browser/ssl/ssl_host_state.h22
-rw-r--r--content/browser/ssl/ssl_host_state_unittest.cc114
-rw-r--r--content/browser/ssl/ssl_policy.cc12
-rw-r--r--content/browser/ssl/ssl_policy_backend.cc16
-rw-r--r--content/browser/ssl/ssl_policy_backend.h20
-rw-r--r--content/browser/startup_task_runner.cc63
-rw-r--r--content/browser/startup_task_runner.h66
-rw-r--r--content/browser/startup_task_runner_unittest.cc281
-rw-r--r--content/browser/storage_partition_impl.cc510
-rw-r--r--content/browser/storage_partition_impl.h35
-rw-r--r--content/browser/storage_partition_impl_map.cc6
-rw-r--r--content/browser/storage_partition_impl_unittest.cc6
-rw-r--r--content/browser/streams/stream.cc2
-rw-r--r--content/browser/web_contents/render_view_host_manager.cc6
-rw-r--r--content/browser/web_contents/web_contents_impl.cc43
-rw-r--r--content/browser/webui/shared_resources_data_source.cc30
147 files changed, 3335 insertions, 1670 deletions
diff --git a/content/browser/DEPS b/content/browser/DEPS
index d61441d09a..39be989190 100644
--- a/content/browser/DEPS
+++ b/content/browser/DEPS
@@ -39,7 +39,6 @@ include_rules = [
"+third_party/WebKit/public/platform/WebGamepads.h",
"+third_party/WebKit/public/platform/WebGraphicsContext3D.h",
"+third_party/WebKit/public/platform/WebIDBCallbacks.h",
- "+third_party/WebKit/public/platform/WebIDBDatabase.h",
"+third_party/WebKit/public/platform/WebIDBDatabaseException.h",
"+third_party/WebKit/public/platform/WebIDBTypes.h",
"+third_party/WebKit/public/platform/WebReferrerPolicy.h",
@@ -49,7 +48,6 @@ include_rules = [
"+third_party/WebKit/public/web/WebCompositionUnderline.h",
"+third_party/WebKit/public/web/WebConsoleMessage.h",
"+third_party/WebKit/public/web/WebCursorInfo.h",
- "+third_party/WebKit/public/web/WebDevToolsAgent.h",
"+third_party/WebKit/public/web/WebDragOperation.h",
"+third_party/WebKit/public/web/WebDragStatus.h",
"+third_party/WebKit/public/web/WebFindOptions.h",
@@ -63,10 +61,7 @@ include_rules = [
"+third_party/WebKit/public/web/WebTextDirection.h",
# These should be burned down. http://crbug.com/237267
- "!third_party/WebKit/public/web/WebBindings.h",
- "!third_party/WebKit/public/web/android/WebInputEventFactory.h",
"!third_party/WebKit/public/web/gtk/WebInputEventFactory.h",
- "!third_party/WebKit/public/web/linux/WebFontInfo.h",
"!third_party/WebKit/public/web/mac/WebInputEventFactory.h",
# DO NOT ADD ANY CHROME OR COMPONENTS INCLUDES HERE!!!
diff --git a/content/browser/accessibility/browser_accessibility_gtk.cc b/content/browser/accessibility/browser_accessibility_gtk.cc
index f5539b78b5..50364282b3 100644
--- a/content/browser/accessibility/browser_accessibility_gtk.cc
+++ b/content/browser/accessibility/browser_accessibility_gtk.cc
@@ -12,11 +12,6 @@
namespace content {
-// The maximum length of an autogenerated unique type name string,
-// generated from the 16-bit interface mask from an AtkObject.
-// 30 is enough for the prefix "WAIType" + 5 hex chars (max) */
-static const int kWAITypeNameLen = 30;
-
static gpointer browser_accessibility_parent_class = NULL;
static BrowserAccessibilityGtk* ToBrowserAccessibilityGtk(
@@ -27,6 +22,150 @@ static BrowserAccessibilityGtk* ToBrowserAccessibilityGtk(
return atk_object->m_object;
}
+//
+// AtkComponent interface.
+//
+
+static BrowserAccessibilityGtk* ToBrowserAccessibilityGtk(
+ AtkComponent* atk_object) {
+ if (!IS_BROWSER_ACCESSIBILITY(atk_object))
+ return NULL;
+
+ return ToBrowserAccessibilityGtk(BROWSER_ACCESSIBILITY(atk_object));
+}
+
+static AtkObject* browser_accessibility_accessible_at_point(
+ AtkComponent* component, gint x, gint y, AtkCoordType coord_type) {
+ BrowserAccessibilityGtk* obj = ToBrowserAccessibilityGtk(component);
+ if (!obj)
+ return NULL;
+
+ gfx::Point point(x, y);
+ if (!obj->GetGlobalBoundsRect().Contains(point))
+ return NULL;
+
+ BrowserAccessibility* result = obj->BrowserAccessibilityForPoint(point);
+ if (!result)
+ return NULL;
+
+ AtkObject* atk_result = result->ToBrowserAccessibilityGtk()->GetAtkObject();
+ g_object_ref(atk_result);
+ return atk_result;
+}
+
+static void browser_accessibility_get_extents(
+ AtkComponent* component, gint* x, gint* y, gint* width, gint* height,
+ AtkCoordType coord_type) {
+ BrowserAccessibilityGtk* obj = ToBrowserAccessibilityGtk(component);
+ if (!obj)
+ return;
+
+ gfx::Rect bounds = obj->GetGlobalBoundsRect();
+ *x = bounds.x();
+ *y = bounds.y();
+ *width = bounds.width();
+ *height = bounds.height();
+}
+
+static gboolean browser_accessibility_grab_focus(AtkComponent* component) {
+ BrowserAccessibilityGtk* obj = ToBrowserAccessibilityGtk(component);
+ if (!obj)
+ return false;
+
+ obj->manager()->SetFocus(obj, true);
+ return true;
+}
+
+static void ComponentInterfaceInit(AtkComponentIface* iface) {
+ iface->ref_accessible_at_point = browser_accessibility_accessible_at_point;
+ iface->get_extents = browser_accessibility_get_extents;
+ iface->grab_focus = browser_accessibility_grab_focus;
+}
+
+static const GInterfaceInfo ComponentInfo = {
+ reinterpret_cast<GInterfaceInitFunc>(ComponentInterfaceInit), 0, 0
+};
+
+//
+// AtkValue interface.
+//
+
+static BrowserAccessibilityGtk* ToBrowserAccessibilityGtk(
+ AtkValue* atk_object) {
+ if (!IS_BROWSER_ACCESSIBILITY(atk_object))
+ return NULL;
+
+ return ToBrowserAccessibilityGtk(BROWSER_ACCESSIBILITY(atk_object));
+}
+
+static void browser_accessibility_get_current_value(
+ AtkValue* atk_object, GValue* value) {
+ BrowserAccessibilityGtk* obj = ToBrowserAccessibilityGtk(atk_object);
+ if (!obj)
+ return;
+
+ float float_val;
+ if (obj->GetFloatAttribute(AccessibilityNodeData::ATTR_VALUE_FOR_RANGE,
+ &float_val)) {
+ memset(value, 0, sizeof(*value));
+ g_value_init(value, G_TYPE_FLOAT);
+ g_value_set_float(value, float_val);
+ }
+}
+
+static void browser_accessibility_get_minimum_value(
+ AtkValue* atk_object, GValue* value) {
+ BrowserAccessibilityGtk* obj = ToBrowserAccessibilityGtk(atk_object);
+ if (!obj)
+ return;
+
+ float float_val;
+ if (obj->GetFloatAttribute(AccessibilityNodeData::ATTR_MIN_VALUE_FOR_RANGE,
+ &float_val)) {
+ memset(value, 0, sizeof(*value));
+ g_value_init(value, G_TYPE_FLOAT);
+ g_value_set_float(value, float_val);
+ }
+}
+
+static void browser_accessibility_get_maximum_value(
+ AtkValue* atk_object, GValue* value) {
+ BrowserAccessibilityGtk* obj = ToBrowserAccessibilityGtk(atk_object);
+ if (!obj)
+ return;
+
+ float float_val;
+ if (obj->GetFloatAttribute(AccessibilityNodeData::ATTR_MAX_VALUE_FOR_RANGE,
+ &float_val)) {
+ memset(value, 0, sizeof(*value));
+ g_value_init(value, G_TYPE_FLOAT);
+ g_value_set_float(value, float_val);
+ }
+}
+
+static void browser_accessibility_get_minimum_increment(
+ AtkValue* atk_object, GValue* value) {
+ // TODO(dmazzoni): get the correct value from an <input type=range>.
+ memset(value, 0, sizeof(*value));
+ g_value_init(value, G_TYPE_FLOAT);
+ g_value_set_float(value, 1.0);
+}
+
+static void ValueInterfaceInit(AtkValueIface* iface) {
+ iface->get_current_value = browser_accessibility_get_current_value;
+ iface->get_minimum_value = browser_accessibility_get_minimum_value;
+ iface->get_maximum_value = browser_accessibility_get_maximum_value;
+ iface->get_minimum_increment = browser_accessibility_get_minimum_increment;
+}
+
+static const GInterfaceInfo ValueInfo = {
+ reinterpret_cast<GInterfaceInitFunc>(ValueInterfaceInit), 0, 0
+};
+
+//
+// AtkObject interface
+//
+
static BrowserAccessibilityGtk* ToBrowserAccessibilityGtk(
AtkObject* atk_object) {
if (!IS_BROWSER_ACCESSIBILITY(atk_object))
@@ -126,6 +265,11 @@ static AtkRelationSet* browser_accessibility_ref_relation_set(
return relation_set;
}
+//
+// The rest of the BrowserAccessibilityGtk code, not specific to one
+// of the Atk* interfaces.
+//
+
static void browser_accessibility_init(AtkObject* atk_object, gpointer data) {
if (ATK_OBJECT_CLASS(browser_accessibility_parent_class)->initialize) {
ATK_OBJECT_CLASS(browser_accessibility_parent_class)->initialize(
@@ -183,64 +327,42 @@ GType browser_accessibility_get_type() {
return type_volatile;
}
-static guint16 GetInterfaceMaskFromObject(BrowserAccessibilityGtk* obj) {
- return 0;
-}
-
-static const char* GetUniqueAccessibilityTypeName(guint16 interface_mask)
+static const char* GetUniqueAccessibilityTypeName(int interface_mask)
{
- static char name[kWAITypeNameLen + 1];
-
- sprintf(name, "WAIType%x", interface_mask);
- name[kWAITypeNameLen] = '\0';
-
+ // 20 characters is enough for "Chrome%x" with any integer value.
+ static char name[20];
+ snprintf(name, sizeof(name), "Chrome%x", interface_mask);
return name;
}
-static const GInterfaceInfo AtkInterfacesInitFunctions[] = {
+enum AtkInterfaces {
+ ATK_ACTION_INTERFACE,
+ ATK_COMPONENT_INTERFACE,
+ ATK_DOCUMENT_INTERFACE,
+ ATK_EDITABLE_TEXT_INTERFACE,
+ ATK_HYPERLINK_INTERFACE,
+ ATK_HYPERTEXT_INTERFACE,
+ ATK_IMAGE_INTERFACE,
+ ATK_SELECTION_INTERFACE,
+ ATK_TABLE_INTERFACE,
+ ATK_TEXT_INTERFACE,
+ ATK_VALUE_INTERFACE,
};
-enum WAIType {
- WAI_ACTION,
- WAI_SELECTION,
- WAI_EDITABLE_TEXT,
- WAI_TEXT,
- WAI_COMPONENT,
- WAI_IMAGE,
- WAI_TABLE,
- WAI_HYPERTEXT,
- WAI_HYPERLINK,
- WAI_DOCUMENT,
- WAI_VALUE,
-};
+static int GetInterfaceMaskFromObject(BrowserAccessibilityGtk* obj) {
+ int interface_mask = 0;
+
+ // Component interface is always supported.
+ interface_mask |= 1 << ATK_COMPONENT_INTERFACE;
-static GType GetAtkInterfaceTypeFromWAIType(WAIType type) {
- switch (type) {
- case WAI_ACTION:
- return ATK_TYPE_ACTION;
- case WAI_SELECTION:
- return ATK_TYPE_SELECTION;
- case WAI_EDITABLE_TEXT:
- return ATK_TYPE_EDITABLE_TEXT;
- case WAI_TEXT:
- return ATK_TYPE_TEXT;
- case WAI_COMPONENT:
- return ATK_TYPE_COMPONENT;
- case WAI_IMAGE:
- return ATK_TYPE_IMAGE;
- case WAI_TABLE:
- return ATK_TYPE_TABLE;
- case WAI_HYPERTEXT:
- return ATK_TYPE_HYPERTEXT;
- case WAI_HYPERLINK:
- return ATK_TYPE_HYPERLINK_IMPL;
- case WAI_DOCUMENT:
- return ATK_TYPE_DOCUMENT;
- case WAI_VALUE:
- return ATK_TYPE_VALUE;
+ int role = obj->role();
+ if (role == AccessibilityNodeData::ROLE_PROGRESS_INDICATOR ||
+ role == AccessibilityNodeData::ROLE_SCROLLBAR ||
+ role == AccessibilityNodeData::ROLE_SLIDER) {
+ interface_mask |= 1 << ATK_VALUE_INTERFACE;
}
- return G_TYPE_INVALID;
+ return interface_mask;
}
static GType GetAccessibilityTypeFromObject(BrowserAccessibilityGtk* obj) {
@@ -257,7 +379,7 @@ static GType GetAccessibilityTypeFromObject(BrowserAccessibilityGtk* obj) {
0 /* value table */
};
- guint16 interface_mask = GetInterfaceMaskFromObject(obj);
+ int interface_mask = GetInterfaceMaskFromObject(obj);
const char* atk_type_name = GetUniqueAccessibilityTypeName(interface_mask);
GType type = g_type_from_name(atk_type_name);
if (type)
@@ -267,14 +389,10 @@ static GType GetAccessibilityTypeFromObject(BrowserAccessibilityGtk* obj) {
atk_type_name,
&type_info,
GTypeFlags(0));
- for (guint i = 0; i < G_N_ELEMENTS(AtkInterfacesInitFunctions); i++) {
- if (interface_mask & (1 << i)) {
- g_type_add_interface_static(
- type,
- GetAtkInterfaceTypeFromWAIType(static_cast<WAIType>(i)),
- &AtkInterfacesInitFunctions[i]);
- }
- }
+ if (interface_mask & (1 << ATK_COMPONENT_INTERFACE))
+ g_type_add_interface_static(type, ATK_TYPE_COMPONENT, &ComponentInfo);
+ if (interface_mask & (1 << ATK_VALUE_INTERFACE))
+ g_type_add_interface_static(type, ATK_TYPE_VALUE, &ValueInfo);
return type;
}
@@ -302,13 +420,14 @@ BrowserAccessibilityGtk* BrowserAccessibility::ToBrowserAccessibilityGtk() {
return static_cast<BrowserAccessibilityGtk*>(this);
}
-BrowserAccessibilityGtk::BrowserAccessibilityGtk() {
- atk_object_ = ATK_OBJECT(browser_accessibility_new(this));
+BrowserAccessibilityGtk::BrowserAccessibilityGtk()
+ : atk_object_(NULL) {
}
BrowserAccessibilityGtk::~BrowserAccessibilityGtk() {
browser_accessibility_detach(BROWSER_ACCESSIBILITY(atk_object_));
- g_object_unref(atk_object_);
+ if (atk_object_)
+ g_object_unref(atk_object_);
}
AtkObject* BrowserAccessibilityGtk::GetAtkObject() const {
@@ -321,10 +440,25 @@ void BrowserAccessibilityGtk::PreInitialize() {
BrowserAccessibility::PreInitialize();
InitRoleAndState();
- if (this->parent()) {
- atk_object_set_parent(
- atk_object_,
- this->parent()->ToBrowserAccessibilityGtk()->GetAtkObject());
+ if (atk_object_) {
+ // If the object's role changes and that causes its
+ // interface mask to change, we need to create a new
+ // AtkObject for it.
+ int interface_mask = GetInterfaceMaskFromObject(this);
+ if (interface_mask != interface_mask_) {
+ g_object_unref(atk_object_);
+ atk_object_ = NULL;
+ }
+ }
+
+ if (!atk_object_) {
+ interface_mask_ = GetInterfaceMaskFromObject(this);
+ atk_object_ = ATK_OBJECT(browser_accessibility_new(this));
+ if (this->parent()) {
+ atk_object_set_parent(
+ atk_object_,
+ this->parent()->ToBrowserAccessibilityGtk()->GetAtkObject());
+ }
}
}
diff --git a/content/browser/accessibility/browser_accessibility_gtk.h b/content/browser/accessibility/browser_accessibility_gtk.h
index ba28b12f7b..8f3a2e31e5 100644
--- a/content/browser/accessibility/browser_accessibility_gtk.h
+++ b/content/browser/accessibility/browser_accessibility_gtk.h
@@ -85,6 +85,7 @@ class BrowserAccessibilityGtk : public BrowserAccessibility {
AtkRole atk_role_;
std::string atk_acc_name_;
std::string atk_acc_description_;
+ int interface_mask_;
private:
DISALLOW_COPY_AND_ASSIGN(BrowserAccessibilityGtk);
diff --git a/content/browser/android/DEPS b/content/browser/android/DEPS
new file mode 100644
index 0000000000..0410b36ac8
--- /dev/null
+++ b/content/browser/android/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+ "+third_party/WebKit/public/web/WebBindings.h", # For java bridge bindings
+]
diff --git a/content/browser/android/browser_jni_registrar.cc b/content/browser/android/browser_jni_registrar.cc
index 25e0c3b926..35da3af3f3 100644
--- a/content/browser/android/browser_jni_registrar.cc
+++ b/content/browser/android/browser_jni_registrar.cc
@@ -9,6 +9,7 @@
#include "content/browser/accessibility/browser_accessibility_android.h"
#include "content/browser/accessibility/browser_accessibility_manager_android.h"
#include "content/browser/android/android_browser_process.h"
+#include "content/browser/android/browser_startup_config.h"
#include "content/browser/android/child_process_launcher_android.h"
#include "content/browser/android/content_settings.h"
#include "content/browser/android/content_video_view.h"
@@ -36,37 +37,37 @@ using content::SurfaceTexturePeerBrowserImpl;
namespace {
base::android::RegistrationMethod kContentRegisteredMethods[] = {
- { "AndroidLocationApiAdapter",
- content::AndroidLocationApiAdapter::RegisterGeolocationService },
- { "AndroidBrowserProcess", content::RegisterAndroidBrowserProcess },
- { "BrowserAccessibilityManager",
- content::RegisterBrowserAccessibilityManager },
- { "ChildProcessLauncher", content::RegisterChildProcessLauncher },
- { "ContentSettings", content::ContentSettings::RegisterContentSettings },
- { "ContentViewRenderView",
- content::ContentViewRenderView::RegisterContentViewRenderView },
- { "ContentVideoView", content::ContentVideoView::RegisterContentVideoView },
- { "ContentViewCore", content::RegisterContentViewCore },
- { "DataFetcherImplAndroid", content::DataFetcherImplAndroid::Register },
- { "DateTimePickerAndroid", content::RegisterDateTimeChooserAndroid },
- { "DownloadControllerAndroidImpl",
- content::DownloadControllerAndroidImpl::RegisterDownloadController },
- { "InterstitialPageDelegateAndroid",
- content::InterstitialPageDelegateAndroid
- ::RegisterInterstitialPageDelegateAndroid },
- { "MediaResourceGetterImpl",
- content::MediaResourceGetterImpl::RegisterMediaResourceGetter },
- { "LoadUrlParams", content::RegisterLoadUrlParams },
- { "PowerSaveBlock", content::RegisterPowerSaveBlocker },
- { "RegisterImeAdapter", content::RegisterImeAdapter },
- { "SpeechRecognizerImplAndroid",
- content::SpeechRecognizerImplAndroid::RegisterSpeechRecognizer },
- { "TouchPoint", content::RegisterTouchPoint },
- { "TracingIntentHandler", content::RegisterTracingIntentHandler },
- { "VibrationMessageFilter", content::VibrationMessageFilter::Register },
- { "WebContentsObserverAndroid", content::RegisterWebContentsObserverAndroid },
- { "WebViewStatics", content::RegisterWebViewStatics },
-};
+ {"AndroidLocationApiAdapter",
+ content::AndroidLocationApiAdapter::RegisterGeolocationService},
+ {"AndroidBrowserProcess", content::RegisterAndroidBrowserProcess},
+ {"BrowserAccessibilityManager",
+ content::RegisterBrowserAccessibilityManager},
+ {"BrowserStartupConfiguration", content::RegisterBrowserStartupConfig},
+ {"ChildProcessLauncher", content::RegisterChildProcessLauncher},
+ {"ContentSettings", content::ContentSettings::RegisterContentSettings},
+ {"ContentViewRenderView",
+ content::ContentViewRenderView::RegisterContentViewRenderView},
+ {"ContentVideoView", content::ContentVideoView::RegisterContentVideoView},
+ {"ContentViewCore", content::RegisterContentViewCore},
+ {"DataFetcherImplAndroid", content::DataFetcherImplAndroid::Register},
+ {"DateTimePickerAndroid", content::RegisterDateTimeChooserAndroid},
+ {"DownloadControllerAndroidImpl",
+ content::DownloadControllerAndroidImpl::RegisterDownloadController},
+ {"InterstitialPageDelegateAndroid",
+ content::InterstitialPageDelegateAndroid::
+ RegisterInterstitialPageDelegateAndroid},
+ {"MediaResourceGetterImpl",
+ content::MediaResourceGetterImpl::RegisterMediaResourceGetter},
+ {"LoadUrlParams", content::RegisterLoadUrlParams},
+ {"PowerSaveBlock", content::RegisterPowerSaveBlocker},
+ {"RegisterImeAdapter", content::RegisterImeAdapter},
+ {"SpeechRecognizerImplAndroid",
+ content::SpeechRecognizerImplAndroid::RegisterSpeechRecognizer},
+ {"TouchPoint", content::RegisterTouchPoint},
+ {"TracingIntentHandler", content::RegisterTracingIntentHandler},
+ {"VibrationMessageFilter", content::VibrationMessageFilter::Register},
+ {"WebContentsObserverAndroid", content::RegisterWebContentsObserverAndroid},
+ {"WebViewStatics", content::RegisterWebViewStatics}, };
} // namespace
diff --git a/content/browser/android/browser_media_player_manager.cc b/content/browser/android/browser_media_player_manager.cc
index 78c1499ca3..dbf0c8f303 100644
--- a/content/browser/android/browser_media_player_manager.cc
+++ b/content/browser/android/browser_media_player_manager.cc
@@ -58,12 +58,12 @@ bool BrowserMediaPlayerManager::OnMessageReceived(const IPC::Message& msg) {
IPC_BEGIN_MESSAGE_MAP(BrowserMediaPlayerManager, msg)
IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_EnterFullscreen, OnEnterFullscreen)
IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_ExitFullscreen, OnExitFullscreen)
- IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_MediaPlayerInitialize, OnInitialize)
- IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_MediaPlayerStart, OnStart)
- IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_MediaPlayerSeek, OnSeek)
- IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_MediaPlayerPause, OnPause)
- IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_MediaPlayerRelease,
- OnReleaseResources)
+ IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_Initialize, OnInitialize)
+ IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_Start, OnStart)
+ IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_Seek, OnSeek)
+ IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_Pause, OnPause)
+ IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_SetVolume, OnSetVolume)
+ IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_Release, OnReleaseResources)
IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_DestroyMediaPlayer, OnDestroyPlayer)
IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_DestroyAllMediaPlayers,
DestroyAllMediaPlayers)
@@ -406,6 +406,12 @@ void BrowserMediaPlayerManager::OnPause(int player_id) {
player->Pause();
}
+void BrowserMediaPlayerManager::OnSetVolume(int player_id, double volume) {
+ MediaPlayerAndroid* player = GetPlayer(player_id);
+ if (player)
+ player->SetVolume(volume);
+}
+
void BrowserMediaPlayerManager::OnReleaseResources(int player_id) {
MediaPlayerAndroid* player = GetPlayer(player_id);
// Don't release the fullscreen player when tab visibility changes,
diff --git a/content/browser/android/browser_media_player_manager.h b/content/browser/android/browser_media_player_manager.h
index 8f192e7a84..7f193e9617 100644
--- a/content/browser/android/browser_media_player_manager.h
+++ b/content/browser/android/browser_media_player_manager.h
@@ -116,6 +116,7 @@ class CONTENT_EXPORT BrowserMediaPlayerManager
virtual void OnStart(int player_id);
virtual void OnSeek(int player_id, base::TimeDelta time);
virtual void OnPause(int player_id);
+ virtual void OnSetVolume(int player_id, double volume);
virtual void OnReleaseResources(int player_id);
virtual void OnDestroyPlayer(int player_id);
virtual void OnDemuxerReady(
diff --git a/content/browser/android/browser_startup_config.cc b/content/browser/android/browser_startup_config.cc
new file mode 100644
index 0000000000..3e74208069
--- /dev/null
+++ b/content/browser/android/browser_startup_config.cc
@@ -0,0 +1,25 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/android/browser_startup_config.h"
+
+#include "base/android/jni_android.h"
+#include "jni/BrowserStartupConfig_jni.h"
+
+namespace content {
+
+bool BrowserMayStartAsynchronously() {
+ JNIEnv* env = base::android::AttachCurrentThread();
+ return Java_BrowserStartupConfig_browserMayStartAsynchonously(env);
+}
+
+void BrowserStartupComplete(int result) {
+ JNIEnv* env = base::android::AttachCurrentThread();
+ Java_BrowserStartupConfig_browserStartupComplete(env, result);
+}
+
+bool RegisterBrowserStartupConfig(JNIEnv* env) {
+ return RegisterNativesImpl(env);
+}
+} // namespace content
diff --git a/content/browser/android/browser_startup_config.h b/content/browser/android/browser_startup_config.h
new file mode 100644
index 0000000000..95575f2bc2
--- /dev/null
+++ b/content/browser/android/browser_startup_config.h
@@ -0,0 +1,18 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_BROWSER_STARTUP_CONFIGURATION_H_
+#define CONTENT_BROWSER_BROWSER_STARTUP_CONFIGURATION_H_
+
+#include <jni.h>
+
+namespace content {
+
+bool BrowserMayStartAsynchronously();
+void BrowserStartupComplete(int result);
+
+bool RegisterBrowserStartupConfig(JNIEnv* env);
+
+} // namespace content
+#endif // CONTENT_BROWSER_BROWSER_STARTUP_CONFIGURATION_H_
diff --git a/content/browser/android/content_video_view.cc b/content/browser/android/content_video_view.cc
index 144ac01aba..4a0fdc67a4 100644
--- a/content/browser/android/content_video_view.cc
+++ b/content/browser/android/content_video_view.cc
@@ -54,7 +54,7 @@ ContentVideoView::ContentVideoView(
ContentVideoView::~ContentVideoView() {
DCHECK(g_content_video_view);
- DCHECK(!GetJavaObject(AttachCurrentThread()).obj());
+ DestroyContentVideoView(true);
g_content_video_view = NULL;
}
@@ -100,13 +100,7 @@ void ContentVideoView::OnPlaybackComplete() {
}
void ContentVideoView::OnExitFullscreen() {
- JNIEnv *env = AttachCurrentThread();
- ScopedJavaLocalRef<jobject> content_video_view = GetJavaObject(env);
- if (!content_video_view.is_null()) {
- Java_ContentVideoView_destroyContentVideoView(env,
- content_video_view.obj());
- j_content_video_view_.reset();
- }
+ DestroyContentVideoView(false);
}
void ContentVideoView::UpdateMediaMetadata() {
@@ -178,4 +172,13 @@ ScopedJavaLocalRef<jobject> ContentVideoView::GetJavaObject(JNIEnv* env) {
return j_content_video_view_.get(env);
}
+void ContentVideoView::DestroyContentVideoView(bool native_view_destroyed) {
+ JNIEnv *env = AttachCurrentThread();
+ ScopedJavaLocalRef<jobject> content_video_view = GetJavaObject(env);
+ if (!content_video_view.is_null()) {
+ Java_ContentVideoView_destroyContentVideoView(env,
+ content_video_view.obj(), native_view_destroyed);
+ j_content_video_view_.reset();
+ }
+}
} // namespace content
diff --git a/content/browser/android/content_video_view.h b/content/browser/android/content_video_view.h
index 2647bb0688..2a86830def 100644
--- a/content/browser/android/content_video_view.h
+++ b/content/browser/android/content_video_view.h
@@ -76,6 +76,10 @@ class ContentVideoView {
base::android::ScopedJavaLocalRef<jobject> GetJavaObject(JNIEnv* env);
private:
+ // Destroy the |j_content_video_view_|. If |native_view_destroyed| is true,
+ // no further calls to the native object is allowed.
+ void DestroyContentVideoView(bool native_view_destroyed);
+
// Object that manages the fullscreen media player. It is responsible for
// handling all the playback controls.
BrowserMediaPlayerManager* manager_;
diff --git a/content/browser/android/content_view_core_impl.cc b/content/browser/android/content_view_core_impl.cc
index cfd19dbc04..80fe628dd0 100644
--- a/content/browser/android/content_view_core_impl.cc
+++ b/content/browser/android/content_view_core_impl.cc
@@ -471,6 +471,14 @@ void ContentViewCoreImpl::ConfirmTouchEvent(InputEventAckState ack_result) {
static_cast<jint>(ack_result));
}
+void ContentViewCoreImpl::UnhandledFlingStartEvent() {
+ JNIEnv* env = AttachCurrentThread();
+ ScopedJavaLocalRef<jobject> j_obj = java_ref_.get(env);
+ if (j_obj.is_null())
+ return;
+ Java_ContentViewCore_unhandledFlingStartEvent(env, j_obj.obj());
+}
+
void ContentViewCoreImpl::HasTouchEventHandlers(bool need_touch_events) {
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jobject> j_obj = java_ref_.get(env);
diff --git a/content/browser/android/content_view_core_impl.h b/content/browser/android/content_view_core_impl.h
index dc5bd584d0..ab7da6d243 100644
--- a/content/browser/android/content_view_core_impl.h
+++ b/content/browser/android/content_view_core_impl.h
@@ -253,6 +253,7 @@ class ContentViewCoreImpl : public ContentViewCore,
bool HasFocus();
void ConfirmTouchEvent(InputEventAckState ack_result);
+ void UnhandledFlingStartEvent();
void HasTouchEventHandlers(bool need_touch_events);
void OnSelectionChanged(const std::string& text);
void OnSelectionBoundsChanged(
diff --git a/content/browser/android/edge_effect.cc b/content/browser/android/edge_effect.cc
index b46d3dafc7..d8411bc1f8 100644
--- a/content/browser/android/edge_effect.cc
+++ b/content/browser/android/edge_effect.cc
@@ -33,11 +33,6 @@ const float kHeldEdgeScaleY = .5f;
const float kMaxGlowHeight = 4.f;
-// Note: The Android version computes the aspect ratio from the source texture;
-// because we use rescaled images, this is precomputed from the original Android
-// textures.
-const float kGlowImageAspectRatioInverse = 0.25f;
-
const float kPullGlowBegin = 1.f;
const float kPullEdgeBegin = 0.6f;
@@ -352,8 +347,9 @@ void EdgeEffect::ApplyToLayers(gfx::SizeF size, Edge edge) {
&dummy_scale_x, &dummy_scale_y,
&glow_image_bounds);
const int glow_height = glow_image_bounds.height();
+ const int glow_width = glow_image_bounds.width();
const int glow_bottom = static_cast<int>(std::min(
- glow_height * glow_scale_y_ * kGlowImageAspectRatioInverse * 0.6f,
+ glow_height * glow_scale_y_ * glow_height / glow_width * 0.6f,
glow_height * kMaxGlowHeight) * dpi_scale_ + 0.5f);
UpdateLayer(glow_.get(), edge, size, glow_bottom, glow_alpha_);
diff --git a/content/browser/android/in_process/synchronous_compositor_output_surface.cc b/content/browser/android/in_process/synchronous_compositor_output_surface.cc
index a65ab1fa4e..fafd06fda2 100644
--- a/content/browser/android/in_process/synchronous_compositor_output_surface.cc
+++ b/content/browser/android/in_process/synchronous_compositor_output_surface.cc
@@ -9,6 +9,7 @@
#include "cc/output/begin_frame_args.h"
#include "cc/output/compositor_frame.h"
#include "cc/output/context_provider.h"
+#include "cc/output/managed_memory_policy.h"
#include "cc/output/output_surface_client.h"
#include "cc/output/software_output_device.h"
#include "content/browser/android/in_process/synchronous_compositor_impl.h"
@@ -124,6 +125,16 @@ bool SynchronousCompositorOutputSurface::BindToClient(
SynchronousCompositorOutputSurfaceDelegate* delegate = GetDelegate();
if (delegate)
delegate->DidBindOutputSurface(this);
+
+ const int bytes_limit = 64 * 1024 * 1024;
+ const int num_resources_limit = 100;
+ surface_client->SetMemoryPolicy(
+ cc::ManagedMemoryPolicy(bytes_limit,
+ cc::ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING,
+ 0,
+ cc::ManagedMemoryPolicy::CUTOFF_ALLOW_NOTHING,
+ num_resources_limit));
+
return true;
}
diff --git a/content/browser/android/overscroll_glow.cc b/content/browser/android/overscroll_glow.cc
index 891201e640..2c9efeea72 100644
--- a/content/browser/android/overscroll_glow.cc
+++ b/content/browser/android/overscroll_glow.cc
@@ -4,10 +4,10 @@
#include "content/browser/android/overscroll_glow.h"
+#include "base/debug/trace_event.h"
#include "base/lazy_instance.h"
#include "cc/layers/image_layer.h"
#include "content/browser/android/edge_effect.h"
-#include "skia/ext/image_operations.h"
#include "ui/gfx/android/java_bitmap.h"
using std::max;
@@ -19,22 +19,16 @@ namespace {
const float kEpsilon = 1e-3f;
-SkBitmap CreateBitmap(const char* resource, gfx::Size size) {
- SkBitmap bitmap = gfx::CreateSkBitmapFromResource(resource);
- if (bitmap.isNull())
- return bitmap;
- return skia::ImageOperations::Resize(bitmap,
- skia::ImageOperations::RESIZE_GOOD,
- size.width(), size.height());
-}
-
class OverscrollResources {
public:
- OverscrollResources()
- : edge_bitmap_(CreateBitmap("android:drawable/overscroll_edge",
- gfx::Size(256, 12))),
- glow_bitmap_(CreateBitmap("android:drawable/overscroll_glow",
- gfx::Size(128, 128))) {
+ OverscrollResources() {
+ TRACE_EVENT0("browser", "OverscrollResources::Create");
+ edge_bitmap_ =
+ gfx::CreateSkBitmapFromResource("android:drawable/overscroll_edge",
+ gfx::Size(128, 12));
+ glow_bitmap_ =
+ gfx::CreateSkBitmapFromResource("android:drawable/overscroll_glow",
+ gfx::Size(128, 64));
}
const SkBitmap& edge_bitmap() { return edge_bitmap_; }
diff --git a/content/browser/aura/OWNERS b/content/browser/aura/OWNERS
index 7b915c61ea..3b61cda829 100644
--- a/content/browser/aura/OWNERS
+++ b/content/browser/aura/OWNERS
@@ -1,3 +1,4 @@
piman@chromium.org
danakj@chromium.org
sievers@chromium.org
+jbauman@chromium.org
diff --git a/content/browser/aura/gpu_process_transport_factory.cc b/content/browser/aura/gpu_process_transport_factory.cc
index 6ac45f7665..2210e8de21 100644
--- a/content/browser/aura/gpu_process_transport_factory.cc
+++ b/content/browser/aura/gpu_process_transport_factory.cc
@@ -32,10 +32,10 @@
#include "ui/gfx/size.h"
#if defined(OS_WIN)
-#include "content/browser/renderer_host/software_output_device_win.h"
+#include "content/browser/aura/software_output_device_win.h"
#include "ui/surface/accelerated_surface_win.h"
#elif defined(USE_X11)
-#include "content/browser/renderer_host/software_output_device_x11.h"
+#include "content/browser/aura/software_output_device_x11.h"
#endif
namespace content {
@@ -197,6 +197,11 @@ scoped_ptr<cc::OutputSurface> CreateSoftwareOutputSurface(
ui::Compositor* compositor) {
scoped_ptr<cc::OutputSurface> output_surface;
+ if (ui::Compositor::WasInitializedWithThread()) {
+ LOG(FATAL) << "Can't use software compositing with browser threaded"
+ " compositing.";
+ }
+
#if defined(OS_WIN)
scoped_ptr<SoftwareOutputDeviceWin> software_device(
new SoftwareOutputDeviceWin(compositor));
@@ -405,14 +410,15 @@ GpuProcessTransportFactory::OffscreenContextProviderForMainThread() {
base::Bind(&GpuProcessTransportFactory::
CreateOffscreenCommandBufferContext,
base::Unretained(this)));
- shared_contexts_main_thread_->SetLostContextCallback(base::Bind(
- &GpuProcessTransportFactory::
- OnLostMainThreadSharedContextInsideCallback,
- callback_factory_.GetWeakPtr()));
-
- if (shared_contexts_main_thread_.get() &&
- !shared_contexts_main_thread_->BindToCurrentThread())
- shared_contexts_main_thread_ = NULL;
+ if (shared_contexts_main_thread_) {
+ shared_contexts_main_thread_->SetLostContextCallback(base::Bind(
+ &GpuProcessTransportFactory::
+ OnLostMainThreadSharedContextInsideCallback,
+ callback_factory_.GetWeakPtr()));
+
+ if (!shared_contexts_main_thread_->BindToCurrentThread())
+ shared_contexts_main_thread_ = NULL;
+ }
}
return shared_contexts_main_thread_;
}
diff --git a/content/browser/renderer_host/software_output_device_win.cc b/content/browser/aura/software_output_device_win.cc
index 6535d4d23e..0332e3e936 100644
--- a/content/browser/renderer_host/software_output_device_win.cc
+++ b/content/browser/aura/software_output_device_win.cc
@@ -1,8 +1,8 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/browser/renderer_host/software_output_device_win.h"
+#include "content/browser/aura/software_output_device_win.h"
#include "content/public/browser/browser_thread.h"
#include "third_party/skia/include/core/SkBitmap.h"
diff --git a/content/browser/renderer_host/software_output_device_win.h b/content/browser/aura/software_output_device_win.h
index e52808609d..93568c2bd5 100644
--- a/content/browser/renderer_host/software_output_device_win.h
+++ b/content/browser/aura/software_output_device_win.h
@@ -1,9 +1,9 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_BROWSER_RENDERER_HOST_SOFTWARE_OUTPUT_DEVICE_WIN_H_
-#define CONTENT_BROWSER_RENDERER_HOST_SOFTWARE_OUTPUT_DEVICE_WIN_H_
+#ifndef CONTENT_BROWSER_AURA_SOFTWARE_OUTPUT_DEVICE_WIN_H_
+#define CONTENT_BROWSER_AURA_SOFTWARE_OUTPUT_DEVICE_WIN_H_
#include "base/memory/scoped_ptr.h"
#include "cc/output/software_output_device.h"
@@ -38,4 +38,4 @@ class SoftwareOutputDeviceWin : public cc::SoftwareOutputDevice {
} // namespace content
-#endif // CONTENT_BROWSER_RENDERER_HOST_SOFTWARE_OUTPUT_DEVICE_WIN_H_
+#endif // CONTENT_BROWSER_AURA_SOFTWARE_OUTPUT_DEVICE_WIN_H_
diff --git a/content/browser/renderer_host/software_output_device_x11.cc b/content/browser/aura/software_output_device_x11.cc
index 2c7ab2283f..229755b6ff 100644
--- a/content/browser/renderer_host/software_output_device_x11.cc
+++ b/content/browser/aura/software_output_device_x11.cc
@@ -1,8 +1,8 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/browser/renderer_host/software_output_device_x11.h"
+#include "content/browser/aura/software_output_device_x11.h"
#include <X11/Xlib.h>
#include <X11/Xutil.h>
diff --git a/content/browser/renderer_host/software_output_device_x11.h b/content/browser/aura/software_output_device_x11.h
index 4c7876a365..986a486d75 100644
--- a/content/browser/renderer_host/software_output_device_x11.h
+++ b/content/browser/aura/software_output_device_x11.h
@@ -1,9 +1,9 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_BROWSER_RENDERER_HOST_SOFTWARE_OUTPUT_DEVICE_X11_H_
-#define CONTENT_BROWSER_RENDERER_HOST_SOFTWARE_OUTPUT_DEVICE_X11_H_
+#ifndef CONTENT_BROWSER_AURA_SOFTWARE_OUTPUT_DEVICE_X11_H_
+#define CONTENT_BROWSER_AURA_SOFTWARE_OUTPUT_DEVICE_X11_H_
#include "cc/output/software_output_device.h"
#include "ui/base/x/x11_util.h"
@@ -35,4 +35,4 @@ class SoftwareOutputDeviceX11 : public cc::SoftwareOutputDevice {
} // namespace content
-#endif // CONTENT_BROWSER_RENDERER_HOST_SOFTWARE_OUTPUT_DEVICE_X11_H_
+#endif // CONTENT_BROWSER_AURA_SOFTWARE_OUTPUT_DEVICE_X11_H_
diff --git a/content/browser/browser_child_process_host_impl.cc b/content/browser/browser_child_process_host_impl.cc
index 6155776e56..780dc6a2d4 100644
--- a/content/browser/browser_child_process_host_impl.cc
+++ b/content/browser/browser_child_process_host_impl.cc
@@ -95,7 +95,8 @@ BrowserChildProcessHostImpl::BrowserChildProcessHostImpl(
int process_type,
BrowserChildProcessHostDelegate* delegate)
: data_(process_type),
- delegate_(delegate) {
+ delegate_(delegate),
+ power_monitor_message_broadcaster_(this) {
data_.id = ChildProcessHostImpl::GenerateChildProcessUniqueId();
child_process_host_.reset(ChildProcessHost::Create(this));
diff --git a/content/browser/browser_child_process_host_impl.h b/content/browser/browser_child_process_host_impl.h
index e25b514415..61971d6d97 100644
--- a/content/browser/browser_child_process_host_impl.h
+++ b/content/browser/browser_child_process_host_impl.h
@@ -12,6 +12,7 @@
#include "base/process/process.h"
#include "base/synchronization/waitable_event_watcher.h"
#include "content/browser/child_process_launcher.h"
+#include "content/browser/power_monitor_message_broadcaster.h"
#include "content/public/browser/browser_child_process_host.h"
#include "content/public/browser/child_process_data.h"
#include "content/public/common/child_process_host_delegate.h"
@@ -104,6 +105,8 @@ class CONTENT_EXPORT BrowserChildProcessHostImpl
scoped_ptr<ChildProcessLauncher> child_process_;
+ PowerMonitorMessageBroadcaster power_monitor_message_broadcaster_;
+
#if defined(OS_WIN)
// Watches to see if the child process exits before the IPC channel has
// been connected. Thereafter, its exit is determined by an error on the
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc
index cc45bc2375..1c6b1a033e 100644
--- a/content/browser/browser_main_loop.cc
+++ b/content/browser/browser_main_loop.cc
@@ -13,6 +13,7 @@
#include "base/metrics/histogram.h"
#include "base/pending_task.h"
#include "base/power_monitor/power_monitor.h"
+#include "base/power_monitor/power_monitor_device_source.h"
#include "base/process/process_metrics.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
@@ -34,6 +35,7 @@
#include "content/browser/renderer_host/media/audio_mirroring_manager.h"
#include "content/browser/renderer_host/media/media_stream_manager.h"
#include "content/browser/speech/speech_recognition_manager_impl.h"
+#include "content/browser/startup_task_runner.h"
#include "content/browser/tracing/trace_controller_impl.h"
#include "content/browser/webui/content_web_ui_controller_factory.h"
#include "content/browser/webui/url_data_manager.h"
@@ -60,6 +62,7 @@
#if defined(OS_ANDROID)
#include "base/android/jni_android.h"
+#include "content/browser/android/browser_startup_config.h"
#include "content/browser/android/surface_texture_peer_browser_impl.h"
#endif
@@ -299,7 +302,8 @@ BrowserMainLoop* BrowserMainLoop::GetInstance() {
BrowserMainLoop::BrowserMainLoop(const MainFunctionParams& parameters)
: parameters_(parameters),
parsed_command_line_(parameters.command_line),
- result_code_(RESULT_CODE_NORMAL_EXIT) {
+ result_code_(RESULT_CODE_NORMAL_EXIT),
+ created_threads_(false) {
DCHECK(!g_current_browser_main_loop);
g_current_browser_main_loop = this;
}
@@ -394,7 +398,9 @@ void BrowserMainLoop::MainMessageLoopStart() {
}
{
TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:PowerMonitor")
- power_monitor_.reset(new base::PowerMonitor);
+ scoped_ptr<base::PowerMonitorSource> power_monitor_source(
+ new base::PowerMonitorDeviceSource());
+ power_monitor_.reset(new base::PowerMonitor(power_monitor_source.Pass()));
}
{
TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:HighResTimerManager")
@@ -483,8 +489,7 @@ void BrowserMainLoop::MainMessageLoopStart() {
#endif
}
-void BrowserMainLoop::CreateThreads() {
- TRACE_EVENT0("startup", "BrowserMainLoop::CreateThreads")
+int BrowserMainLoop::PreCreateThreads() {
if (parts_) {
TRACE_EVENT0("startup",
@@ -509,9 +514,44 @@ void BrowserMainLoop::CreateThreads() {
if (parsed_command_line_.HasSwitch(switches::kSingleProcess))
RenderProcessHost::SetRunRendererInProcess(true);
#endif
+ return result_code_;
+}
- if (result_code_ > 0)
- return;
+void BrowserMainLoop::CreateStartupTasks() {
+ TRACE_EVENT0("startup", "BrowserMainLoop::CreateStartupTasks")
+
+#if defined(OS_ANDROID)
+ scoped_refptr<StartupTaskRunner> task_runner =
+ new StartupTaskRunner(BrowserMayStartAsynchronously(),
+ base::Bind(&BrowserStartupComplete),
+ base::MessageLoop::current()->message_loop_proxy());
+#else
+ scoped_refptr<StartupTaskRunner> task_runner =
+ new StartupTaskRunner(false,
+ base::Callback<void(int)>(),
+ base::MessageLoop::current()->message_loop_proxy());
+#endif
+ StartupTask pre_create_threads =
+ base::Bind(&BrowserMainLoop::PreCreateThreads, base::Unretained(this));
+ task_runner->AddTask(pre_create_threads);
+
+ StartupTask create_threads =
+ base::Bind(&BrowserMainLoop::CreateThreads, base::Unretained(this));
+ task_runner->AddTask(create_threads);
+
+ StartupTask browser_thread_started = base::Bind(
+ &BrowserMainLoop::BrowserThreadsStarted, base::Unretained(this));
+ task_runner->AddTask(browser_thread_started);
+
+ StartupTask pre_main_message_loop_run = base::Bind(
+ &BrowserMainLoop::PreMainMessageLoopRun, base::Unretained(this));
+ task_runner->AddTask(pre_main_message_loop_run);
+
+ task_runner->StartRunningTasks();
+}
+
+int BrowserMainLoop::CreateThreads() {
+ TRACE_EVENT0("startup", "BrowserMainLoop::CreateThreads");
base::Thread::Options default_options;
base::Thread::Options io_message_loop_options;
@@ -596,14 +636,11 @@ void BrowserMainLoop::CreateThreads() {
TRACE_EVENT_END0("startup", "BrowserMainLoop::CreateThreads:start");
}
+ created_threads_ = true;
+ return result_code_;
+}
-#if !defined(OS_IOS)
- indexed_db_thread_.reset(new base::Thread("IndexedDB"));
- indexed_db_thread_->Start();
-#endif
-
- BrowserThreadsStarted();
-
+int BrowserMainLoop::PreMainMessageLoopRun() {
if (parts_) {
TRACE_EVENT0("startup",
"BrowserMainLoop::CreateThreads:PreMainMessageLoopRun");
@@ -614,6 +651,7 @@ void BrowserMainLoop::CreateThreads() {
// Do not allow disk IO from the UI thread.
base::ThreadRestrictions::SetIOAllowed(false);
base::ThreadRestrictions::DisallowWaiting();
+ return result_code_;
}
void BrowserMainLoop::RunMainMessageLoopParts() {
@@ -630,6 +668,11 @@ void BrowserMainLoop::RunMainMessageLoopParts() {
}
void BrowserMainLoop::ShutdownThreadsAndCleanUp() {
+
+ if (!created_threads_) {
+ // Called early, nothing to do
+ return;
+ }
// Teardown may start in PostMainMessageLoopRun, and during teardown we
// need to be able to perform IO.
base::ThreadRestrictions::SetIOAllowed(true);
@@ -765,8 +808,14 @@ void BrowserMainLoop::InitializeMainThread() {
new BrowserThreadImpl(BrowserThread::UI, base::MessageLoop::current()));
}
-void BrowserMainLoop::BrowserThreadsStarted() {
+int BrowserMainLoop::BrowserThreadsStarted() {
TRACE_EVENT0("startup", "BrowserMainLoop::BrowserThreadsStarted")
+
+#if !defined(OS_IOS)
+ indexed_db_thread_.reset(new base::Thread("IndexedDB"));
+ indexed_db_thread_->Start();
+#endif
+
#if defined(OS_ANDROID)
// Up the priority of anything that touches with display tasks
// (this thread is UI thread, and io_thread_ is for IPCs).
@@ -844,6 +893,7 @@ void BrowserMainLoop::BrowserThreadsStarted() {
CAUSE_FOR_GPU_LAUNCH_BROWSER_STARTUP));
}
#endif // !defined(OS_IOS)
+ return result_code_;
}
void BrowserMainLoop::InitializeToolkit() {
diff --git a/content/browser/browser_main_loop.h b/content/browser/browser_main_loop.h
index 5c3608bc87..7b2879f70e 100644
--- a/content/browser/browser_main_loop.h
+++ b/content/browser/browser_main_loop.h
@@ -6,8 +6,10 @@
#define CONTENT_BROWSER_BROWSER_MAIN_LOOP_H_
#include "base/basictypes.h"
+#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/browser_process_sub_thread.h"
+#include "content/public/browser/browser_main_runner.h"
class CommandLine;
@@ -65,8 +67,8 @@ class CONTENT_EXPORT BrowserMainLoop {
void InitializeToolkit();
void MainMessageLoopStart();
- // Create all secondary threads.
- void CreateThreads();
+ // Create the tasks we need to complete startup.
+ void CreateStartupTasks();
// Perform the default message loop run logic.
void RunMainMessageLoopParts();
@@ -94,8 +96,16 @@ class CONTENT_EXPORT BrowserMainLoop {
void InitializeMainThread();
+ // Called just before creating the threads
+ int PreCreateThreads();
+
+ // Create all secondary threads.
+ int CreateThreads();
+
// Called right after the browser threads have been started.
- void BrowserThreadsStarted();
+ int BrowserThreadsStarted();
+
+ int PreMainMessageLoopRun();
void MainMessageLoopRun();
@@ -103,6 +113,8 @@ class CONTENT_EXPORT BrowserMainLoop {
const MainFunctionParams& parameters_;
const CommandLine& parsed_command_line_;
int result_code_;
+ // True if the non-UI threads were created.
+ bool created_threads_;
// Members initialized in |MainMessageLoopStart()| ---------------------------
scoped_ptr<base::MessageLoop> main_message_loop_;
diff --git a/content/browser/browser_main_runner.cc b/content/browser/browser_main_runner.cc
index f50832af1b..cca1466d9b 100644
--- a/content/browser/browser_main_runner.cc
+++ b/content/browser/browser_main_runner.cc
@@ -29,11 +29,7 @@ namespace content {
class BrowserMainRunnerImpl : public BrowserMainRunner {
public:
- BrowserMainRunnerImpl()
- : is_initialized_(false),
- is_shutdown_(false),
- created_threads_(false) {
- }
+ BrowserMainRunnerImpl() : is_initialized_(false), is_shutdown_(false) {}
virtual ~BrowserMainRunnerImpl() {
if (is_initialized_ && !is_shutdown_)
@@ -102,11 +98,10 @@ class BrowserMainRunnerImpl : public BrowserMainRunner {
#endif
ui::InitializeInputMethod();
- main_loop_->CreateThreads();
+ main_loop_->CreateStartupTasks();
int result_code = main_loop_->GetResultCode();
if (result_code > 0)
return result_code;
- created_threads_ = true;
// Return -1 to indicate no early termination.
return -1;
@@ -124,8 +119,7 @@ class BrowserMainRunnerImpl : public BrowserMainRunner {
DCHECK(!is_shutdown_);
g_exited_main_message_loop = true;
- if (created_threads_)
- main_loop_->ShutdownThreadsAndCleanUp();
+ main_loop_->ShutdownThreadsAndCleanUp();
ui::ShutdownInputMethod();
#if defined(OS_WIN)
@@ -146,9 +140,6 @@ class BrowserMainRunnerImpl : public BrowserMainRunner {
// True if the runner has been shut down.
bool is_shutdown_;
- // True if the non-UI threads were created.
- bool created_threads_;
-
scoped_ptr<NotificationServiceImpl> notification_service_;
scoped_ptr<BrowserMainLoop> main_loop_;
#if defined(OS_WIN)
diff --git a/content/browser/browser_plugin/browser_plugin_guest.cc b/content/browser/browser_plugin/browser_plugin_guest.cc
index 23277d6cf6..7b6253d7dc 100644
--- a/content/browser/browser_plugin/browser_plugin_guest.cc
+++ b/content/browser/browser_plugin/browser_plugin_guest.cc
@@ -1417,9 +1417,12 @@ void BrowserPluginGuest::OnUnlockMouseAck(int instance_id) {
void BrowserPluginGuest::OnUpdateRectACK(
int instance_id,
+ bool needs_ack,
const BrowserPluginHostMsg_AutoSize_Params& auto_size_params,
const BrowserPluginHostMsg_ResizeGuest_Params& resize_guest_params) {
- Send(new ViewMsg_UpdateRect_ACK(routing_id()));
+ // Only the software path expects an ACK.
+ if (needs_ack)
+ Send(new ViewMsg_UpdateRect_ACK(routing_id()));
OnSetSize(instance_id_, auto_size_params, resize_guest_params);
}
@@ -1552,7 +1555,11 @@ bool BrowserPluginGuest::HandleJavaScriptDialog(
return false;
}
-void BrowserPluginGuest::ResetJavaScriptState(WebContents* web_contents) {
+void BrowserPluginGuest::CancelActiveAndPendingDialogs(
+ WebContents* web_contents) {
+}
+
+void BrowserPluginGuest::WebContentsDestroyed(WebContents* web_contents) {
}
void BrowserPluginGuest::OnUpdateRect(
diff --git a/content/browser/browser_plugin/browser_plugin_guest.h b/content/browser/browser_plugin/browser_plugin_guest.h
index c9c7b6bd1f..7e1d1c00bd 100644
--- a/content/browser/browser_plugin/browser_plugin_guest.h
+++ b/content/browser/browser_plugin/browser_plugin_guest.h
@@ -222,7 +222,9 @@ class CONTENT_EXPORT BrowserPluginGuest
virtual bool HandleJavaScriptDialog(WebContents* web_contents,
bool accept,
const string16* prompt_override) OVERRIDE;
- virtual void ResetJavaScriptState(WebContents* web_contents) OVERRIDE;
+ virtual void CancelActiveAndPendingDialogs(
+ WebContents* web_contents) OVERRIDE;
+ virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE;
// Exposes the protected web_contents() from WebContentsObserver.
WebContentsImpl* GetWebContents();
@@ -410,6 +412,7 @@ class CONTENT_EXPORT BrowserPluginGuest
void OnUpdateGeometry(int instance_id, const gfx::Rect& view_rect);
void OnUpdateRectACK(
int instance_id,
+ bool needs_ack,
const BrowserPluginHostMsg_AutoSize_Params& auto_size_params,
const BrowserPluginHostMsg_ResizeGuest_Params& resize_guest_params);
diff --git a/content/browser/byte_stream.cc b/content/browser/byte_stream.cc
index f83e8c3164..d1f5e175b2 100644
--- a/content/browser/byte_stream.cc
+++ b/content/browser/byte_stream.cc
@@ -55,7 +55,8 @@ class ByteStreamWriterImpl : public ByteStreamWriter {
// Overridden from ByteStreamWriter.
virtual bool Write(scoped_refptr<net::IOBuffer> buffer,
size_t byte_count) OVERRIDE;
- virtual void Close(DownloadInterruptReason status) OVERRIDE;
+ virtual void Flush() OVERRIDE;
+ virtual void Close(int status) OVERRIDE;
virtual void RegisterCallback(const base::Closure& source_callback) OVERRIDE;
// PostTask target from |ByteStreamReaderImpl::MaybeUpdateInput|.
@@ -67,7 +68,7 @@ class ByteStreamWriterImpl : public ByteStreamWriter {
// Called from UpdateWindow when object existence has been validated.
void UpdateWindowInternal(size_t bytes_consumed);
- void PostToPeer(bool complete, DownloadInterruptReason status);
+ void PostToPeer(bool complete, int status);
const size_t total_buffer_size_;
@@ -113,10 +114,10 @@ class ByteStreamReaderImpl : public ByteStreamReader {
// Overridden from ByteStreamReader.
virtual StreamState Read(scoped_refptr<net::IOBuffer>* data,
size_t* length) OVERRIDE;
- virtual DownloadInterruptReason GetStatus() const OVERRIDE;
+ virtual int GetStatus() const OVERRIDE;
virtual void RegisterCallback(const base::Closure& sink_callback) OVERRIDE;
- // PostTask target from |ByteStreamWriterImpl::MaybePostToPeer| and
+ // PostTask target from |ByteStreamWriterImpl::Write| and
// |ByteStreamWriterImpl::Close|.
// Receive data from our peer.
// static because it may be called after the object it is targeting
@@ -128,7 +129,7 @@ class ByteStreamReaderImpl : public ByteStreamReader {
scoped_ptr<ContentVector> transfer_buffer,
size_t transfer_buffer_bytes,
bool source_complete,
- DownloadInterruptReason status);
+ int status);
private:
// Called from TransferData once object existence has been validated.
@@ -136,7 +137,7 @@ class ByteStreamReaderImpl : public ByteStreamReader {
scoped_ptr<ContentVector> transfer_buffer,
size_t transfer_buffer_bytes,
bool source_complete,
- DownloadInterruptReason status);
+ int status);
void MaybeUpdateInput();
@@ -150,7 +151,7 @@ class ByteStreamReaderImpl : public ByteStreamReader {
ContentVector available_contents_;
bool received_status_;
- DownloadInterruptReason status_;
+ int status_;
base::Closure data_available_callback_;
@@ -210,13 +211,18 @@ bool ByteStreamWriterImpl::Write(
// Arbitrarily, we buffer to a third of the total size before sending.
if (input_contents_size_ > total_buffer_size_ / kFractionBufferBeforeSending)
- PostToPeer(false, DOWNLOAD_INTERRUPT_REASON_NONE);
+ PostToPeer(false, 0);
return (input_contents_size_ + output_size_used_ <= total_buffer_size_);
}
-void ByteStreamWriterImpl::Close(
- DownloadInterruptReason status) {
+void ByteStreamWriterImpl::Flush() {
+ DCHECK(my_task_runner_->RunsTasksOnCurrentThread());
+ if (input_contents_size_ > 0)
+ PostToPeer(false, 0);
+}
+
+void ByteStreamWriterImpl::Close(int status) {
DCHECK(my_task_runner_->RunsTasksOnCurrentThread());
PostToPeer(true, status);
}
@@ -252,8 +258,7 @@ void ByteStreamWriterImpl::UpdateWindowInternal(size_t bytes_consumed) {
space_available_callback_.Run();
}
-void ByteStreamWriterImpl::PostToPeer(
- bool complete, DownloadInterruptReason status) {
+void ByteStreamWriterImpl::PostToPeer(bool complete, int status) {
DCHECK(my_task_runner_->RunsTasksOnCurrentThread());
// Valid contexts in which to call.
DCHECK(complete || 0 != input_contents_size_);
@@ -286,7 +291,7 @@ ByteStreamReaderImpl::ByteStreamReaderImpl(
my_task_runner_(task_runner),
my_lifetime_flag_(lifetime_flag),
received_status_(false),
- status_(DOWNLOAD_INTERRUPT_REASON_NONE),
+ status_(0),
unreported_consumed_bytes_(0),
peer_(NULL) {
DCHECK(my_lifetime_flag_.get());
@@ -326,7 +331,7 @@ ByteStreamReaderImpl::Read(scoped_refptr<net::IOBuffer>* data,
return STREAM_EMPTY;
}
-DownloadInterruptReason ByteStreamReaderImpl::GetStatus() const {
+int ByteStreamReaderImpl::GetStatus() const {
DCHECK(my_task_runner_->RunsTasksOnCurrentThread());
DCHECK(received_status_);
return status_;
@@ -346,7 +351,7 @@ void ByteStreamReaderImpl::TransferData(
scoped_ptr<ContentVector> transfer_buffer,
size_t buffer_size,
bool source_complete,
- DownloadInterruptReason status) {
+ int status) {
// If our target is no longer alive, do nothing.
if (!object_lifetime_flag->is_alive) return;
@@ -358,7 +363,7 @@ void ByteStreamReaderImpl::TransferDataInternal(
scoped_ptr<ContentVector> transfer_buffer,
size_t buffer_size,
bool source_complete,
- DownloadInterruptReason status) {
+ int status) {
DCHECK(my_task_runner_->RunsTasksOnCurrentThread());
bool was_empty = available_contents_.empty();
diff --git a/content/browser/byte_stream.h b/content/browser/byte_stream.h
index 49b7674905..b16664f314 100644
--- a/content/browser/byte_stream.h
+++ b/content/browser/byte_stream.h
@@ -12,7 +12,7 @@
#include "base/callback.h"
#include "base/memory/ref_counted.h"
#include "base/synchronization/lock.h"
-#include "content/public/browser/download_interrupt_reasons.h"
+#include "content/common/content_export.h"
#include "net/base/io_buffer.h"
namespace base {
@@ -33,8 +33,10 @@ namespace content {
// and the sink retrieves bytes already written via |ByteStreamReader::Read|.
//
// When the source has no more data to add, it will call
-// |ByteStreamWriter::Close| to indicate that. Errors at the source
-// are indicated to the sink via a non-DOWNLOAD_INTERRUPT_REASON_NONE code.
+// |ByteStreamWriter::Close| to indicate that. Operation status at the source
+// is indicated to the sink via an int passed to the Close() method and returned
+// from the GetStatus() method. Source and sink must agree on the interpretation
+// of this int.
//
// Normally the source is not managed after the relationship is setup;
// it is expected to provide data and then close itself. If an error
@@ -113,7 +115,7 @@ namespace content {
// }
//
// if (ByteStreamReader::STREAM_COMPLETE == state) {
-// DownloadInterruptReason status = reader->GetStatus();
+// int status = reader->GetStatus();
// // Process error or successful completion in |status|.
// }
//
@@ -121,7 +123,7 @@ namespace content {
// // again when there's more data.
// }
class CONTENT_EXPORT ByteStreamWriter {
-public:
+ public:
// Inverse of the fraction of the stream buffer that must be full before
// a notification is sent to paired Reader that there's more data.
static const int kFractionBufferBeforeSending;
@@ -134,10 +136,15 @@ public:
virtual bool Write(scoped_refptr<net::IOBuffer> buffer,
size_t byte_count) = 0;
+ // Flushes contents buffered in this writer to the corresponding reader
+ // regardless if buffer filling rate is greater than
+ // kFractionBufferBeforeSending or not. Does nothing if there's no contents
+ // buffered.
+ virtual void Flush() = 0;
+
// Signal that all data that is going to be sent, has been sent,
- // and provide a status. |DOWNLOAD_INTERRUPT_REASON_NONE| should be
- // passed for successful completion.
- virtual void Close(DownloadInterruptReason status) = 0;
+ // and provide a status.
+ virtual void Close(int status) = 0;
// Register a callback to be called when the stream transitions from
// full to having space available. The callback will always be
@@ -172,7 +179,7 @@ class CONTENT_EXPORT ByteStreamReader {
size_t* length) = 0;
// Only valid to call if Read() has returned STREAM_COMPLETE.
- virtual DownloadInterruptReason GetStatus() const = 0;
+ virtual int GetStatus() const = 0;
// Register a callback to be called when data is added or the source
// completes. The callback will be always be called on the owning
diff --git a/content/browser/byte_stream_unittest.cc b/content/browser/byte_stream_unittest.cc
index ed413da8f3..925467c06a 100644
--- a/content/browser/byte_stream_unittest.cc
+++ b/content/browser/byte_stream_unittest.cc
@@ -115,7 +115,7 @@ TEST_F(ByteStreamTest, ByteStream_PushBack) {
EXPECT_FALSE(Write(byte_stream_input.get(), 1));
EXPECT_FALSE(Write(byte_stream_input.get(), 1024));
// Flush
- byte_stream_input->Close(DOWNLOAD_INTERRUPT_REASON_NONE);
+ byte_stream_input->Close(0);
message_loop_.RunUntilIdle();
// Pull the IO buffers out; do we get the same buffers and do they
@@ -146,6 +146,45 @@ TEST_F(ByteStreamTest, ByteStream_PushBack) {
byte_stream_output->Read(&output_io_buffer, &output_length));
}
+// Confirm that Flush() method makes the writer to send written contents to
+// the reader.
+TEST_F(ByteStreamTest, ByteStream_Flush) {
+ scoped_ptr<ByteStreamWriter> byte_stream_input;
+ scoped_ptr<ByteStreamReader> byte_stream_output;
+ CreateByteStream(
+ message_loop_.message_loop_proxy(), message_loop_.message_loop_proxy(),
+ 1024, &byte_stream_input, &byte_stream_output);
+
+ EXPECT_TRUE(Write(byte_stream_input.get(), 1));
+ message_loop_.RunUntilIdle();
+
+ scoped_refptr<net::IOBuffer> output_io_buffer;
+ size_t output_length = 0;
+ // Check that data is not sent to the reader yet.
+ EXPECT_EQ(ByteStreamReader::STREAM_EMPTY,
+ byte_stream_output->Read(&output_io_buffer, &output_length));
+
+ byte_stream_input->Flush();
+ message_loop_.RunUntilIdle();
+
+ EXPECT_EQ(ByteStreamReader::STREAM_HAS_DATA,
+ byte_stream_output->Read(&output_io_buffer, &output_length));
+ EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
+
+ // Check that it's ok to Flush() an empty writer.
+ byte_stream_input->Flush();
+ message_loop_.RunUntilIdle();
+
+ EXPECT_EQ(ByteStreamReader::STREAM_EMPTY,
+ byte_stream_output->Read(&output_io_buffer, &output_length));
+
+ byte_stream_input->Close(0);
+ message_loop_.RunUntilIdle();
+
+ EXPECT_EQ(ByteStreamReader::STREAM_COMPLETE,
+ byte_stream_output->Read(&output_io_buffer, &output_length));
+}
+
// Same as above, only use knowledge of the internals to confirm
// that we're getting pushback even when data's split across the two
// objects
@@ -212,12 +251,11 @@ TEST_F(ByteStreamTest, ByteStream_CompleteTransmits) {
3 * 1024, &byte_stream_input, &byte_stream_output);
EXPECT_EQ(ByteStreamReader::STREAM_EMPTY,
byte_stream_output->Read(&output_io_buffer, &output_length));
- byte_stream_input->Close(DOWNLOAD_INTERRUPT_REASON_NONE);
+ byte_stream_input->Close(0);
message_loop_.RunUntilIdle();
ASSERT_EQ(ByteStreamReader::STREAM_COMPLETE,
byte_stream_output->Read(&output_io_buffer, &output_length));
- EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
- byte_stream_output->GetStatus());
+ EXPECT_EQ(0, byte_stream_output->GetStatus());
// Non-empty stream, non-error case.
CreateByteStream(
@@ -226,45 +264,44 @@ TEST_F(ByteStreamTest, ByteStream_CompleteTransmits) {
EXPECT_EQ(ByteStreamReader::STREAM_EMPTY,
byte_stream_output->Read(&output_io_buffer, &output_length));
EXPECT_TRUE(Write(byte_stream_input.get(), 1024));
- byte_stream_input->Close(DOWNLOAD_INTERRUPT_REASON_NONE);
+ byte_stream_input->Close(0);
message_loop_.RunUntilIdle();
EXPECT_EQ(ByteStreamReader::STREAM_HAS_DATA,
byte_stream_output->Read(&output_io_buffer, &output_length));
EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
ASSERT_EQ(ByteStreamReader::STREAM_COMPLETE,
byte_stream_output->Read(&output_io_buffer, &output_length));
- EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
- byte_stream_output->GetStatus());
+ EXPECT_EQ(0, byte_stream_output->GetStatus());
- // Empty stream, non-error case.
+ const int kFakeErrorCode = 22;
+
+ // Empty stream, error case.
CreateByteStream(
message_loop_.message_loop_proxy(), message_loop_.message_loop_proxy(),
3 * 1024, &byte_stream_input, &byte_stream_output);
EXPECT_EQ(ByteStreamReader::STREAM_EMPTY,
byte_stream_output->Read(&output_io_buffer, &output_length));
- byte_stream_input->Close(DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED);
+ byte_stream_input->Close(kFakeErrorCode);
message_loop_.RunUntilIdle();
ASSERT_EQ(ByteStreamReader::STREAM_COMPLETE,
byte_stream_output->Read(&output_io_buffer, &output_length));
- EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED,
- byte_stream_output->GetStatus());
+ EXPECT_EQ(kFakeErrorCode, byte_stream_output->GetStatus());
- // Non-empty stream, non-error case.
+ // Non-empty stream, error case.
CreateByteStream(
message_loop_.message_loop_proxy(), message_loop_.message_loop_proxy(),
3 * 1024, &byte_stream_input, &byte_stream_output);
EXPECT_EQ(ByteStreamReader::STREAM_EMPTY,
byte_stream_output->Read(&output_io_buffer, &output_length));
EXPECT_TRUE(Write(byte_stream_input.get(), 1024));
- byte_stream_input->Close(DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED);
+ byte_stream_input->Close(kFakeErrorCode);
message_loop_.RunUntilIdle();
EXPECT_EQ(ByteStreamReader::STREAM_HAS_DATA,
byte_stream_output->Read(&output_io_buffer, &output_length));
EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
ASSERT_EQ(ByteStreamReader::STREAM_COMPLETE,
byte_stream_output->Read(&output_io_buffer, &output_length));
- EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED,
- byte_stream_output->GetStatus());
+ EXPECT_EQ(kFakeErrorCode, byte_stream_output->GetStatus());
}
// Confirm that callbacks on the sink side are triggered when they should be.
@@ -499,7 +536,7 @@ TEST_F(ByteStreamTest, ByteStream_ZeroCallback) {
base::Bind(CountCallbacks, &num_callbacks));
// Immediately close the stream.
- byte_stream_input->Close(DOWNLOAD_INTERRUPT_REASON_NONE);
+ byte_stream_input->Close(0);
task_runner->RunUntilIdle();
EXPECT_EQ(1, num_callbacks);
}
diff --git a/content/browser/device_orientation/data_fetcher_shared_memory.h b/content/browser/device_orientation/data_fetcher_shared_memory.h
index 8168e87134..dc5e92ae16 100644
--- a/content/browser/device_orientation/data_fetcher_shared_memory.h
+++ b/content/browser/device_orientation/data_fetcher_shared_memory.h
@@ -14,31 +14,39 @@ class WebDeviceMotionData;
namespace content {
-class DataFetcherSharedMemory {
+class CONTENT_EXPORT DataFetcherSharedMemory {
public:
- DataFetcherSharedMemory() : device_motion_buffer_(NULL) { }
+ DataFetcherSharedMemory()
+ : device_motion_buffer_(NULL),
+ started_(false) { }
virtual ~DataFetcherSharedMemory();
// Returns true if this fetcher needs explicit calls to fetch the data.
+ // Called from any thread.
virtual bool NeedsPolling();
// If this fetcher NeedsPolling() is true, this method will update the
// buffer with the latest device motion data.
- // This method will do nothing if NeedsPolling() is false.
// Returns true if there was any motion data to update the buffer with.
+ // Called from the DeviceMotionProvider::PollingThread.
virtual bool FetchDeviceMotionDataIntoBuffer();
// Returns true if the relevant sensors could be successfully activated.
// This method should be called before any calls to
// FetchDeviceMotionDataIntoBuffer().
+ // If NeedsPolling() is true this method should be called from the
+ // PollingThread.
virtual bool StartFetchingDeviceMotionData(
DeviceMotionHardwareBuffer* buffer);
// Indicates to the fetcher to stop fetching device data.
+ // If NeedsPolling() is true this method should be called from the
+ // PollingThread.
virtual void StopFetchingDeviceMotionData();
private:
DeviceMotionHardwareBuffer* device_motion_buffer_;
+ bool started_;
DISALLOW_COPY_AND_ASSIGN(DataFetcherSharedMemory);
};
diff --git a/content/browser/device_orientation/data_fetcher_shared_memory_android.cc b/content/browser/device_orientation/data_fetcher_shared_memory_android.cc
index 5a87c6d32e..b051557670 100644
--- a/content/browser/device_orientation/data_fetcher_shared_memory_android.cc
+++ b/content/browser/device_orientation/data_fetcher_shared_memory_android.cc
@@ -10,7 +10,8 @@
namespace content {
DataFetcherSharedMemory::~DataFetcherSharedMemory() {
- StopFetchingDeviceMotionData();
+ if (started_)
+ StopFetchingDeviceMotionData();
}
bool DataFetcherSharedMemory::NeedsPolling() {
@@ -24,13 +25,16 @@ bool DataFetcherSharedMemory::FetchDeviceMotionDataIntoBuffer() {
bool DataFetcherSharedMemory::StartFetchingDeviceMotionData(
DeviceMotionHardwareBuffer* buffer) {
+ DCHECK(buffer);
device_motion_buffer_ = buffer;
return DataFetcherImplAndroid::GetInstance()->
StartFetchingDeviceMotionData(buffer);
+ started_ = true;
}
void DataFetcherSharedMemory::StopFetchingDeviceMotionData() {
- DataFetcherImplAndroid::GetInstance()->StopFetchingDeviceMotionData();
+ DataFetcherImplAndroid::GetInstance()->StopFetchingDeviceMotionData();
+ started_ = false;
}
} // namespace content
diff --git a/content/browser/device_orientation/data_fetcher_shared_memory_default.cc b/content/browser/device_orientation/data_fetcher_shared_memory_default.cc
index 819605cb8a..0f66fc7977 100644
--- a/content/browser/device_orientation/data_fetcher_shared_memory_default.cc
+++ b/content/browser/device_orientation/data_fetcher_shared_memory_default.cc
@@ -9,7 +9,8 @@
namespace content {
DataFetcherSharedMemory::~DataFetcherSharedMemory() {
- StopFetchingDeviceMotionData();
+ if (started_)
+ StopFetchingDeviceMotionData();
}
bool DataFetcherSharedMemory::NeedsPolling() {
@@ -24,9 +25,11 @@ bool DataFetcherSharedMemory::FetchDeviceMotionDataIntoBuffer() {
bool DataFetcherSharedMemory::StartFetchingDeviceMotionData(
DeviceMotionHardwareBuffer* buffer) {
DCHECK(buffer);
+ device_motion_buffer_ = buffer;
device_motion_buffer_->seqlock.WriteBegin();
device_motion_buffer_->data.allAvailableSensorsAreActive = true;
device_motion_buffer_->seqlock.WriteEnd();
+ started_ = true;
return true;
}
@@ -34,6 +37,7 @@ void DataFetcherSharedMemory::StopFetchingDeviceMotionData() {
device_motion_buffer_->seqlock.WriteBegin();
device_motion_buffer_->data.allAvailableSensorsAreActive = false;
device_motion_buffer_->seqlock.WriteEnd();
+ started_ = false;
}
} // namespace content
diff --git a/content/browser/device_orientation/device_motion_provider.cc b/content/browser/device_orientation/device_motion_provider.cc
index 84f65cabd1..e88d5af83f 100644
--- a/content/browser/device_orientation/device_motion_provider.cc
+++ b/content/browser/device_orientation/device_motion_provider.cc
@@ -4,14 +4,95 @@
#include "content/browser/device_orientation/device_motion_provider.h"
+#include "base/bind.h"
#include "base/logging.h"
+#include "base/threading/thread.h"
+#include "base/timer/timer.h"
#include "content/browser/device_orientation/data_fetcher_shared_memory.h"
#include "content/common/device_motion_hardware_buffer.h"
namespace content {
+namespace {
+const int kPeriodInMilliseconds = 100;
+}
+
+class DeviceMotionProvider::PollingThread : public base::Thread {
+ public:
+ explicit PollingThread(const char* name);
+ virtual ~PollingThread();
+
+ void StartPolling(DataFetcherSharedMemory* fetcher,
+ DeviceMotionHardwareBuffer* buffer);
+ void StopPolling();
+
+ private:
+ void DoPoll();
+
+ scoped_ptr<base::RepeatingTimer<PollingThread> > timer_;
+ DataFetcherSharedMemory* fetcher_;
+
+ DISALLOW_COPY_AND_ASSIGN(PollingThread);
+};
+
+// ---- PollingThread methods
+
+DeviceMotionProvider::PollingThread::PollingThread(const char* name)
+ : base::Thread(name) {
+}
+
+DeviceMotionProvider::PollingThread::~PollingThread() {
+}
+
+void DeviceMotionProvider::PollingThread::StartPolling(
+ DataFetcherSharedMemory* fetcher, DeviceMotionHardwareBuffer* buffer) {
+ DCHECK(base::MessageLoop::current() == message_loop());
+ DCHECK(!timer_);
+
+ fetcher_ = fetcher;
+ fetcher_->StartFetchingDeviceMotionData(buffer);
+ timer_.reset(new base::RepeatingTimer<PollingThread>());
+ timer_->Start(FROM_HERE,
+ base::TimeDelta::FromMilliseconds(kPeriodInMilliseconds),
+ this, &PollingThread::DoPoll);
+}
+
+void DeviceMotionProvider::PollingThread::StopPolling() {
+ DCHECK(base::MessageLoop::current() == message_loop());
+ DCHECK(fetcher_);
+ // this will also stop the timer before killing it.
+ timer_.reset();
+ fetcher_->StopFetchingDeviceMotionData();
+}
+
+void DeviceMotionProvider::PollingThread::DoPoll() {
+ DCHECK(base::MessageLoop::current() == message_loop());
+ fetcher_->FetchDeviceMotionDataIntoBuffer();
+}
+
+// ---- end PollingThread methods
+
DeviceMotionProvider::DeviceMotionProvider()
: is_started_(false) {
+ Initialize();
+}
+
+DeviceMotionProvider::DeviceMotionProvider(
+ scoped_ptr<DataFetcherSharedMemory> fetcher)
+ : is_started_(false) {
+ data_fetcher_ = fetcher.Pass();
+ Initialize();
+}
+
+DeviceMotionProvider::~DeviceMotionProvider() {
+ StopFetchingDeviceMotionData();
+ // make sure polling thread stops before data_fetcher_ gets deleted.
+ if (polling_thread_)
+ polling_thread_->Stop();
+ data_fetcher_.reset();
+}
+
+void DeviceMotionProvider::Initialize() {
size_t data_size = sizeof(DeviceMotionHardwareBuffer);
bool res = device_motion_shared_memory_.CreateAndMapAnonymous(data_size);
// TODO(timvolodine): consider not crashing the browser if the check fails.
@@ -20,9 +101,6 @@ DeviceMotionProvider::DeviceMotionProvider()
memset(hwbuf, 0, sizeof(DeviceMotionHardwareBuffer));
}
-DeviceMotionProvider::~DeviceMotionProvider() {
-}
-
base::SharedMemoryHandle DeviceMotionProvider::GetSharedMemoryHandleForProcess(
base::ProcessHandle process) {
base::SharedMemoryHandle renderer_handle;
@@ -33,20 +111,59 @@ base::SharedMemoryHandle DeviceMotionProvider::GetSharedMemoryHandleForProcess(
void DeviceMotionProvider::StartFetchingDeviceMotionData() {
if (is_started_)
return;
+
if (!data_fetcher_)
data_fetcher_.reset(new DataFetcherSharedMemory);
- data_fetcher_->StartFetchingDeviceMotionData(SharedMemoryAsHardwareBuffer());
+
+ if (data_fetcher_->NeedsPolling()) {
+ if (!polling_thread_)
+ CreateAndStartPollingThread();
+
+ polling_thread_->message_loop()->PostTask(
+ FROM_HERE,
+ base::Bind(&PollingThread::StartPolling,
+ base::Unretained(polling_thread_.get()),
+ data_fetcher_.get(),
+ SharedMemoryAsHardwareBuffer()));
+ } else {
+ data_fetcher_->StartFetchingDeviceMotionData(
+ SharedMemoryAsHardwareBuffer());
+ }
+
is_started_ = true;
}
+void DeviceMotionProvider::CreateAndStartPollingThread() {
+ polling_thread_.reset(
+ new PollingThread("Device Motion poller"));
+
+ if (!polling_thread_->Start()) {
+ LOG(ERROR) << "Failed to start Device Motion data polling thread";
+ return;
+ }
+}
+
void DeviceMotionProvider::StopFetchingDeviceMotionData() {
- if (data_fetcher_)
+ if (!is_started_)
+ return;
+
+ DCHECK(data_fetcher_);
+
+ if (data_fetcher_->NeedsPolling()) {
+ DCHECK(polling_thread_);
+ polling_thread_->message_loop()->PostTask(
+ FROM_HERE,
+ base::Bind(&PollingThread::StopPolling,
+ base::Unretained(polling_thread_.get())));
+ } else {
data_fetcher_->StopFetchingDeviceMotionData();
+ }
+
is_started_ = false;
}
-DeviceMotionHardwareBuffer* DeviceMotionProvider::
- SharedMemoryAsHardwareBuffer() {
+DeviceMotionHardwareBuffer*
+DeviceMotionProvider::SharedMemoryAsHardwareBuffer() {
void* mem = device_motion_shared_memory_.memory();
CHECK(mem);
return static_cast<DeviceMotionHardwareBuffer*>(mem);
diff --git a/content/browser/device_orientation/device_motion_provider.h b/content/browser/device_orientation/device_motion_provider.h
index 90588dac58..8fd36de33d 100644
--- a/content/browser/device_orientation/device_motion_provider.h
+++ b/content/browser/device_orientation/device_motion_provider.h
@@ -13,9 +13,18 @@
namespace content {
class DataFetcherSharedMemory;
+// This class owns the shared memory buffer for Device Motion and makes
+// sure the data is fetched into that buffer.
+// When DataFetcherSharedMemory::NeedsPolling() is true, it starts a
+// background polling thread to make sure the data is fetched at regular
+// intervals.
class CONTENT_EXPORT DeviceMotionProvider {
public:
DeviceMotionProvider();
+
+ // Creates provider with a custom fetcher. Used for testing.
+ explicit DeviceMotionProvider(scoped_ptr<DataFetcherSharedMemory> fetcher);
+
virtual ~DeviceMotionProvider();
// Returns the shared memory handle of the device motion data duplicated
@@ -23,18 +32,20 @@ class CONTENT_EXPORT DeviceMotionProvider {
base::SharedMemoryHandle GetSharedMemoryHandleForProcess(
base::ProcessHandle renderer_process);
- // Pause and resume the background polling thread. Can be called from any
- // thread.
void StartFetchingDeviceMotionData();
void StopFetchingDeviceMotionData();
private:
- base::SharedMemory device_motion_shared_memory_;
+ class PollingThread;
+
+ void Initialize();
+ void CreateAndStartPollingThread();
DeviceMotionHardwareBuffer* SharedMemoryAsHardwareBuffer();
+ base::SharedMemory device_motion_shared_memory_;
scoped_ptr<DataFetcherSharedMemory> data_fetcher_;
-
+ scoped_ptr<PollingThread> polling_thread_;
bool is_started_;
DISALLOW_COPY_AND_ASSIGN(DeviceMotionProvider);
diff --git a/content/browser/device_orientation/device_motion_provider_unittest.cc b/content/browser/device_orientation/device_motion_provider_unittest.cc
new file mode 100644
index 0000000000..cd0f3d843e
--- /dev/null
+++ b/content/browser/device_orientation/device_motion_provider_unittest.cc
@@ -0,0 +1,98 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/device_orientation/device_motion_provider.h"
+
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/synchronization/waitable_event.h"
+#include "content/browser/device_orientation/data_fetcher_shared_memory.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+namespace {
+
+const int kPeriodInMilliseconds = 100;
+
+class FakeDataFetcherSharedMemory : public DataFetcherSharedMemory {
+ public:
+ FakeDataFetcherSharedMemory()
+ : start_fetching_data_(false, false),
+ stop_fetching_data_(false, false),
+ fetched_data_(false, false) {
+ }
+ virtual ~FakeDataFetcherSharedMemory() { }
+
+ virtual bool NeedsPolling() OVERRIDE {
+ return true;
+ }
+
+ virtual bool FetchDeviceMotionDataIntoBuffer() OVERRIDE {
+ buffer_->seqlock.WriteBegin();
+ buffer_->data.interval = kPeriodInMilliseconds;
+ buffer_->seqlock.WriteEnd();
+ fetched_data_.Signal();
+ return true;
+ }
+
+ virtual bool StartFetchingDeviceMotionData(
+ DeviceMotionHardwareBuffer* buffer) OVERRIDE {
+ buffer_ = buffer;
+ start_fetching_data_.Signal();
+ return true;
+ }
+
+ virtual void StopFetchingDeviceMotionData() OVERRIDE {
+ stop_fetching_data_.Signal();
+ }
+
+ void WaitForStart() {
+ start_fetching_data_.Wait();
+ }
+
+ void WaitForStop() {
+ stop_fetching_data_.Wait();
+ }
+
+ void WaitForDataFetch() {
+ fetched_data_.Wait();
+ }
+
+ DeviceMotionHardwareBuffer* GetBuffer() {
+ return buffer_;
+ }
+
+ private:
+ base::WaitableEvent start_fetching_data_;
+ base::WaitableEvent stop_fetching_data_;
+ base::WaitableEvent fetched_data_;
+ DeviceMotionHardwareBuffer* buffer_;
+
+ DISALLOW_COPY_AND_ASSIGN(FakeDataFetcherSharedMemory);
+};
+
+
+TEST(DeviceMotionProviderTest, DoesPolling) {
+ FakeDataFetcherSharedMemory* mock_data_fetcher =
+ new FakeDataFetcherSharedMemory();
+ EXPECT_TRUE(mock_data_fetcher->NeedsPolling());
+
+ scoped_ptr<DeviceMotionProvider> provider(new DeviceMotionProvider(
+ scoped_ptr<DataFetcherSharedMemory>(mock_data_fetcher)));
+
+ provider->StartFetchingDeviceMotionData();
+ mock_data_fetcher->WaitForStart();
+ mock_data_fetcher->WaitForDataFetch();
+
+ EXPECT_EQ(kPeriodInMilliseconds,
+ mock_data_fetcher->GetBuffer()->data.interval);
+
+ provider->StopFetchingDeviceMotionData();
+ mock_data_fetcher->WaitForStop();
+}
+
+} // namespace
+
+} // namespace content
diff --git a/content/browser/device_orientation/motion.cc b/content/browser/device_orientation/motion.cc
deleted file mode 100644
index d5985e66a1..0000000000
--- a/content/browser/device_orientation/motion.cc
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/device_orientation/motion.h"
-
-#include "content/common/device_motion_messages.h"
-
-namespace content {
-
-Motion::Motion()
- : can_provide_acceleration_x_(false),
- can_provide_acceleration_y_(false),
- can_provide_acceleration_z_(false),
- can_provide_acceleration_including_gravity_x_(false),
- can_provide_acceleration_including_gravity_y_(false),
- can_provide_acceleration_including_gravity_z_(false),
- can_provide_rotation_rate_alpha_(false),
- can_provide_rotation_rate_beta_(false),
- can_provide_rotation_rate_gamma_(false),
- can_provide_interval_(false) {
-}
-
-Motion::~Motion() {
-}
-
-IPC::Message* Motion::CreateIPCMessage(int render_view_id) const {
- DeviceMotionMsg_Updated_Params params;
-
- params.can_provide_acceleration_x = can_provide_acceleration_x_;
- params.acceleration_x = acceleration_x_;
- params.can_provide_acceleration_y = can_provide_acceleration_y_;
- params.acceleration_y = acceleration_y_;
- params.can_provide_acceleration_z = can_provide_acceleration_z_;
- params.acceleration_z = acceleration_z_;
-
- params.can_provide_acceleration_including_gravity_x =
- can_provide_acceleration_including_gravity_x_;
- params.acceleration_including_gravity_x = acceleration_including_gravity_x_;
- params.can_provide_acceleration_including_gravity_y =
- can_provide_acceleration_including_gravity_y_;
- params.acceleration_including_gravity_y = acceleration_including_gravity_y_;
- params.can_provide_acceleration_including_gravity_z =
- can_provide_acceleration_including_gravity_z_;
- params.acceleration_including_gravity_z = acceleration_including_gravity_z_;
-
- params.can_provide_rotation_rate_alpha = can_provide_rotation_rate_alpha_;
- params.rotation_rate_alpha = rotation_rate_alpha_;
- params.can_provide_rotation_rate_beta = can_provide_rotation_rate_beta_;
- params.rotation_rate_beta = rotation_rate_beta_;
- params.can_provide_rotation_rate_gamma = can_provide_rotation_rate_gamma_;
- params.rotation_rate_gamma = rotation_rate_gamma_;
-
- params.can_provide_interval = can_provide_interval_;
- params.interval = interval_;
-
- return new DeviceMotionMsg_Updated(render_view_id, params);
-}
-
-// Should always fire new motion events so that they occur at regular intervals.
-// The firing frequency is determined by the polling frequency in ProviderImpl.
-bool Motion::ShouldFireEvent(const DeviceData* old_data) const {
- return true;
-}
-
-}; // namespace content
diff --git a/content/browser/device_orientation/motion.h b/content/browser/device_orientation/motion.h
deleted file mode 100644
index 8027254b99..0000000000
--- a/content/browser/device_orientation/motion.h
+++ /dev/null
@@ -1,165 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_DEVICE_ORIENTATION_MOTION_H_
-#define CONTENT_BROWSER_DEVICE_ORIENTATION_MOTION_H_
-
-#include "base/compiler_specific.h"
-#include "content/browser/device_orientation/device_data.h"
-#include "content/common/content_export.h"
-
-namespace content {
-
-class Motion : public DeviceData {
- public:
- // acceleration_x, acceleration_y, and acceleration_z are the accelerations
- // excluding gravity along the axes specified in
- // http://dev.w3.org/geo/api/spec-source-orientation.html
-
- // acceleration_including_gravity_x, acceleration_including_gravity_y, and
- // acceleration_including_gravity_z are the accelerations including gravity
- // along the same axes as above
-
- // rotation_rate_alpha, rotation_rate_beta, and rotataion_rate_gamma are the
- // rotations around the same axes as above
-
- // interval is the time interval at which data is obtained from the hardware,
- // as specified in the document referenced above
-
- // can_provide_{acceleration_x, acceleration_y, acceleration_z,
- // acceleration_including_gravity_x, acceleration_including_gravity_y,
- // acceleration_including_gravity_z, rotation_rate_alpha, rotation_rate_beta,
- // rotation_rate_gamma, interval} is true if data can be provided for that
- // variable
- CONTENT_EXPORT Motion();
-
- // From DeviceData.
- virtual IPC::Message* CreateIPCMessage(int render_view_id) const OVERRIDE;
- virtual bool ShouldFireEvent(const DeviceData* old_data) const OVERRIDE;
-
- void set_acceleration_x(double acceleration_x) {
- can_provide_acceleration_x_ = true;
- acceleration_x_ = acceleration_x;
- }
- bool can_provide_acceleration_x() const {
- return can_provide_acceleration_x_;
- }
- double acceleration_x() const { return acceleration_x_; }
-
- void set_acceleration_y(double acceleration_y) {
- can_provide_acceleration_y_ = true;
- acceleration_y_ = acceleration_y;
- }
- bool can_provide_acceleration_y() const {
- return can_provide_acceleration_y_;
- }
- double acceleration_y() const { return acceleration_y_; }
-
- void set_acceleration_z(double acceleration_z) {
- can_provide_acceleration_z_ = true;
- acceleration_z_ = acceleration_z;
- }
- bool can_provide_acceleration_z() const {
- return can_provide_acceleration_z_;
- }
- double acceleration_z() const { return acceleration_z_; }
-
- void set_acceleration_including_gravity_x(
- double acceleration_including_gravity_x) {
- can_provide_acceleration_including_gravity_x_ = true;
- acceleration_including_gravity_x_ = acceleration_including_gravity_x;
- }
- bool can_provide_acceleration_including_gravity_x() const {
- return can_provide_acceleration_x_;
- }
- double acceleration_including_gravity_x() const {
- return acceleration_including_gravity_x_;
- }
-
- void set_acceleration_including_gravity_y(
- double acceleration_including_gravity_y) {
- can_provide_acceleration_including_gravity_y_ = true;
- acceleration_including_gravity_y_ = acceleration_including_gravity_y;
- }
- bool can_provide_acceleration_including_gravity_y() const {
- return can_provide_acceleration_y_;
- }
- double acceleration_including_gravity_y() const {
- return acceleration_including_gravity_y_;
- }
-
- void set_acceleration_including_gravity_z(
- double acceleration_including_gravity_z) {
- can_provide_acceleration_including_gravity_z_ = true;
- acceleration_including_gravity_z_ = acceleration_including_gravity_z;
- }
- bool can_provide_acceleration_including_gravity_z() const {
- return can_provide_acceleration_z_;
- }
- double acceleration_including_gravity_z() const {
- return acceleration_including_gravity_z_;
- }
-
- void set_rotation_rate_alpha(double rotation_rate_alpha) {
- can_provide_rotation_rate_alpha_ = true;
- rotation_rate_alpha_ = rotation_rate_alpha;
- }
- bool can_provide_rotation_rate_alpha() const {
- return can_provide_rotation_rate_alpha_;
- }
- double rotation_rate_alpha() const { return rotation_rate_alpha_; }
-
- void set_rotation_rate_beta(double rotation_rate_beta) {
- can_provide_rotation_rate_beta_ = true;
- rotation_rate_beta_ = rotation_rate_beta;
- }
- bool can_provide_rotation_rate_beta() const {
- return can_provide_rotation_rate_beta_;
- }
- double rotation_rate_beta() const { return rotation_rate_beta_; }
-
- void set_rotation_rate_gamma(double rotation_rate_gamma) {
- can_provide_rotation_rate_gamma_ = true;
- rotation_rate_gamma_ = rotation_rate_gamma;
- }
- bool can_provide_rotation_rate_gamma() const {
- return can_provide_rotation_rate_gamma_;
- }
- double rotation_rate_gamma() const { return rotation_rate_gamma_; }
-
- void set_interval(double interval) {
- can_provide_interval_ = true;
- interval_ = interval;
- }
- bool can_provide_interval() const { return can_provide_interval_; }
- double interval() const { return interval_; }
-
- private:
- virtual ~Motion();
-
- double acceleration_x_;
- double acceleration_y_;
- double acceleration_z_;
- double acceleration_including_gravity_x_;
- double acceleration_including_gravity_y_;
- double acceleration_including_gravity_z_;
- double rotation_rate_alpha_;
- double rotation_rate_beta_;
- double rotation_rate_gamma_;
- double interval_;
- bool can_provide_acceleration_x_;
- bool can_provide_acceleration_y_;
- bool can_provide_acceleration_z_;
- bool can_provide_acceleration_including_gravity_x_;
- bool can_provide_acceleration_including_gravity_y_;
- bool can_provide_acceleration_including_gravity_z_;
- bool can_provide_rotation_rate_alpha_;
- bool can_provide_rotation_rate_beta_;
- bool can_provide_rotation_rate_gamma_;
- bool can_provide_interval_;
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_DEVICE_ORIENTATION_MOTION_H_
diff --git a/content/browser/device_orientation/motion_message_filter.cc b/content/browser/device_orientation/motion_message_filter.cc
deleted file mode 100644
index e837ed3b82..0000000000
--- a/content/browser/device_orientation/motion_message_filter.cc
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/device_orientation/motion_message_filter.h"
-
-#include "content/browser/device_orientation/device_data.h"
-#include "content/common/device_motion_messages.h"
-#include "content/public/browser/browser_thread.h"
-
-namespace content {
-
-MotionMessageFilter::MotionMessageFilter()
- : DeviceOrientationMessageFilter(DeviceData::kTypeMotion) {
-}
-
-MotionMessageFilter::~MotionMessageFilter() {
-}
-
-bool MotionMessageFilter::OnMessageReceived(const IPC::Message& message,
- bool* message_was_ok) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP_EX(MotionMessageFilter, message, *message_was_ok)
- IPC_MESSAGE_HANDLER(DeviceMotionHostMsg_StartUpdating, OnStartUpdating)
- IPC_MESSAGE_HANDLER(DeviceMotionHostMsg_StopUpdating, OnStopUpdating)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
- return handled;
-}
-
-} // namespace content
diff --git a/content/browser/device_orientation/motion_message_filter.h b/content/browser/device_orientation/motion_message_filter.h
deleted file mode 100644
index cc50f6765f..0000000000
--- a/content/browser/device_orientation/motion_message_filter.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_DEVICE_ORIENTATION_MOTION_MESSAGE_FILTER_H_
-#define CONTENT_BROWSER_DEVICE_ORIENTATION_MOTION_MESSAGE_FILTER_H_
-
-#include <map>
-
-#include "content/browser/device_orientation/message_filter.h"
-
-namespace content {
-
-class MotionMessageFilter : public DeviceOrientationMessageFilter {
- public:
- MotionMessageFilter();
-
- // DeviceOrientationMessageFilter implementation.
- virtual bool OnMessageReceived(const IPC::Message& message,
- bool* message_was_ok) OVERRIDE;
-
- private:
- virtual ~MotionMessageFilter();
-
- DISALLOW_COPY_AND_ASSIGN(MotionMessageFilter);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_DEVICE_ORIENTATION_MOTION_MESSAGE_FILTER_H_
diff --git a/content/browser/device_orientation/observer_delegate.cc b/content/browser/device_orientation/observer_delegate.cc
index 1ffe07a774..5c233109dd 100644
--- a/content/browser/device_orientation/observer_delegate.cc
+++ b/content/browser/device_orientation/observer_delegate.cc
@@ -6,7 +6,6 @@
#include "base/logging.h"
#include "content/browser/device_orientation/device_data.h"
-#include "content/browser/device_orientation/motion.h"
#include "content/browser/device_orientation/orientation.h"
#include "ipc/ipc_sender.h"
@@ -37,10 +36,9 @@ void ObserverDelegate::OnDeviceDataUpdate(
DeviceData* ObserverDelegate::EmptyDeviceData(DeviceData::Type type) {
switch (type) {
- case DeviceData::kTypeMotion:
- return new Motion();
case DeviceData::kTypeOrientation:
return new Orientation();
+ case DeviceData::kTypeMotion:
case DeviceData::kTypeTest:
NOTREACHED();
}
diff --git a/content/browser/device_orientation/provider_unittest.cc b/content/browser/device_orientation/provider_unittest.cc
index cc502486ef..1f310ea3ad 100644
--- a/content/browser/device_orientation/provider_unittest.cc
+++ b/content/browser/device_orientation/provider_unittest.cc
@@ -9,7 +9,6 @@
#include "base/synchronization/lock.h"
#include "content/browser/device_orientation/data_fetcher.h"
#include "content/browser/device_orientation/device_data.h"
-#include "content/browser/device_orientation/motion.h"
#include "content/browser/device_orientation/orientation.h"
#include "content/browser/device_orientation/provider.h"
#include "content/browser/device_orientation/provider_impl.h"
@@ -71,91 +70,6 @@ class UpdateChecker : public Provider::Observer {
std::queue<scoped_refptr<const DeviceData> > expectations_queue_;
};
-// Class for checking expectations on motion updates from the Provider.
-class MotionUpdateChecker : public UpdateChecker {
- public:
- explicit MotionUpdateChecker(int* expectations_count_ptr)
- : UpdateChecker(DeviceData::kTypeMotion, expectations_count_ptr) {
- }
-
- virtual ~MotionUpdateChecker() {}
-
- // From UpdateChecker.
- virtual void OnDeviceDataUpdate(const DeviceData* device_data,
- DeviceData::Type device_data_type) OVERRIDE {
- ASSERT_FALSE(expectations_queue_.empty());
- ASSERT_EQ(DeviceData::kTypeMotion, device_data_type);
-
- scoped_refptr<const Motion> motion(static_cast<const Motion*>(device_data));
- if (motion.get() == NULL)
- motion = new Motion();
-
- scoped_refptr<const Motion> expected(static_cast<const Motion*>(
- (expectations_queue_.front().get())));
- expectations_queue_.pop();
-
- EXPECT_EQ(expected->can_provide_acceleration_x(),
- motion->can_provide_acceleration_x());
- EXPECT_EQ(expected->can_provide_acceleration_y(),
- motion->can_provide_acceleration_y());
- EXPECT_EQ(expected->can_provide_acceleration_z(),
- motion->can_provide_acceleration_z());
-
- EXPECT_EQ(expected->can_provide_acceleration_including_gravity_x(),
- motion->can_provide_acceleration_including_gravity_x());
- EXPECT_EQ(expected->can_provide_acceleration_including_gravity_y(),
- motion->can_provide_acceleration_including_gravity_y());
- EXPECT_EQ(expected->can_provide_acceleration_including_gravity_z(),
- motion->can_provide_acceleration_including_gravity_z());
-
- EXPECT_EQ(expected->can_provide_rotation_rate_alpha(),
- motion->can_provide_rotation_rate_alpha());
- EXPECT_EQ(expected->can_provide_rotation_rate_beta(),
- motion->can_provide_rotation_rate_beta());
- EXPECT_EQ(expected->can_provide_rotation_rate_gamma(),
- motion->can_provide_rotation_rate_gamma());
-
- EXPECT_EQ(expected->can_provide_interval(), motion->can_provide_interval());
-
- if (expected->can_provide_acceleration_x())
- EXPECT_EQ(expected->acceleration_x(), motion->acceleration_x());
- if (expected->can_provide_acceleration_y())
- EXPECT_EQ(expected->acceleration_y(), motion->acceleration_y());
- if (expected->can_provide_acceleration_z())
- EXPECT_EQ(expected->acceleration_z(), motion->acceleration_z());
-
- if (expected->can_provide_acceleration_including_gravity_x())
- EXPECT_EQ(expected->acceleration_including_gravity_x(),
- motion->acceleration_including_gravity_x());
- if (expected->can_provide_acceleration_including_gravity_y())
- EXPECT_EQ(expected->acceleration_including_gravity_y(),
- motion->acceleration_including_gravity_y());
- if (expected->can_provide_acceleration_including_gravity_z())
- EXPECT_EQ(expected->acceleration_including_gravity_z(),
- motion->acceleration_including_gravity_z());
-
- if (expected->can_provide_rotation_rate_alpha())
- EXPECT_EQ(expected->rotation_rate_alpha(),
- motion->rotation_rate_alpha());
- if (expected->can_provide_rotation_rate_beta())
- EXPECT_EQ(expected->rotation_rate_beta(),
- motion->rotation_rate_beta());
- if (expected->can_provide_rotation_rate_gamma())
- EXPECT_EQ(expected->rotation_rate_gamma(),
- motion->rotation_rate_gamma());
-
- if (expected->can_provide_interval())
- EXPECT_EQ(expected->interval(), motion->interval());
-
- --(*expectations_count_ptr_);
-
- if (*expectations_count_ptr_ == 0) {
- base::MessageLoop::current()->PostTask(FROM_HERE,
- base::MessageLoop::QuitClosure());
- }
- }
-};
-
// Class for checking expectations on orientation updates from the Provider.
class OrientationUpdateChecker : public UpdateChecker {
public:
@@ -612,44 +526,6 @@ TEST_F(DeviceOrientationProviderTest, StartStopStart) {
MockDeviceDataFactory::SetCurInstance(NULL);
}
-// Tests that Motion events always fire, even if the motion is unchanged.
-TEST_F(DeviceOrientationProviderTest, FLAKY_MotionAlwaysFires) {
- scoped_refptr<MockDeviceDataFactory> device_data_factory(
- new MockDeviceDataFactory());
- MockDeviceDataFactory::SetCurInstance(device_data_factory.get());
- Init(MockDeviceDataFactory::CreateDataFetcher);
-
- scoped_refptr<Motion> test_motion(new Motion());
- test_motion->set_acceleration_x(1);
- test_motion->set_acceleration_y(2);
- test_motion->set_acceleration_z(3);
- test_motion->set_acceleration_including_gravity_x(4);
- test_motion->set_acceleration_including_gravity_y(5);
- test_motion->set_acceleration_including_gravity_z(6);
- test_motion->set_rotation_rate_alpha(7);
- test_motion->set_rotation_rate_beta(8);
- test_motion->set_rotation_rate_gamma(9);
- test_motion->set_interval(10);
-
- scoped_ptr<MotionUpdateChecker> checker(new MotionUpdateChecker(
- &pending_expectations_));
-
- device_data_factory->SetDeviceData(test_motion.get(),
- DeviceData::kTypeMotion);
- checker->AddExpectation(test_motion.get());
- provider_->AddObserver(checker.get());
- base::MessageLoop::current()->Run();
-
- // The observer should receive the same motion again.
- device_data_factory->SetDeviceData(test_motion.get(),
- DeviceData::kTypeMotion);
- checker->AddExpectation(test_motion.get());
- base::MessageLoop::current()->Run();
-
- provider_->RemoveObserver(checker.get());
- MockDeviceDataFactory::SetCurInstance(NULL);
-}
-
// Tests that Orientation events only fire if the change is significant.
TEST_F(DeviceOrientationProviderTest, OrientationSignificantlyDifferent) {
scoped_refptr<MockDeviceDataFactory> device_data_factory(
diff --git a/content/browser/devtools/devtools_http_handler_impl.cc b/content/browser/devtools/devtools_http_handler_impl.cc
index 6afc65d6dd..0893547f3f 100644
--- a/content/browser/devtools/devtools_http_handler_impl.cc
+++ b/content/browser/devtools/devtools_http_handler_impl.cc
@@ -542,7 +542,7 @@ void DevToolsHttpHandlerImpl::OnJsonRequestUI(
std::sort(page_list.begin(), page_list.end(), TimeComparator);
base::ListValue* target_list = new base::ListValue();
- std::string host = info.headers["Host"];
+ std::string host = info.headers["host"];
for (PageList::iterator i = page_list.begin(); i != page_list.end(); ++i)
target_list->Append(SerializePageInfo(i->first, host));
@@ -570,7 +570,7 @@ void DevToolsHttpHandlerImpl::OnJsonRequestUI(
"Could not create new page");
return;
}
- std::string host = info.headers["Host"];
+ std::string host = info.headers["host"];
scoped_ptr<base::DictionaryValue> dictionary(SerializePageInfo(rvh, host));
SendJson(connection_id, net::HTTP_OK, dictionary.get(), std::string());
return;
diff --git a/content/browser/download/download_file_impl.cc b/content/browser/download/download_file_impl.cc
index edd7fed527..bbe317b13a 100644
--- a/content/browser/download/download_file_impl.cc
+++ b/content/browser/download/download_file_impl.cc
@@ -232,7 +232,8 @@ void DownloadFileImpl::StreamActive() {
break;
case ByteStreamReader::STREAM_COMPLETE:
{
- reason = stream_reader_->GetStatus();
+ reason = static_cast<DownloadInterruptReason>(
+ stream_reader_->GetStatus());
SendUpdate();
base::TimeTicks close_start(base::TimeTicks::Now());
file_.Finish();
diff --git a/content/browser/download/download_file_unittest.cc b/content/browser/download/download_file_unittest.cc
index a3aafffbcc..ebf501d92c 100644
--- a/content/browser/download/download_file_unittest.cc
+++ b/content/browser/download/download_file_unittest.cc
@@ -41,7 +41,7 @@ class MockByteStreamReader : public ByteStreamReader {
// ByteStream functions
MOCK_METHOD2(Read, ByteStreamReader::StreamState(
scoped_refptr<net::IOBuffer>*, size_t*));
- MOCK_CONST_METHOD0(GetStatus, DownloadInterruptReason());
+ MOCK_CONST_METHOD0(GetStatus, int());
MOCK_METHOD1(RegisterCallback, void(const base::Closure&));
};
diff --git a/content/browser/download/download_item_impl.cc b/content/browser/download/download_item_impl.cc
index b49a256f31..e54ab9e90b 100644
--- a/content/browser/download/download_item_impl.cc
+++ b/content/browser/download/download_item_impl.cc
@@ -1398,6 +1398,8 @@ void DownloadItemImpl::Interrupt(DownloadInterruptReason reason) {
TransitionTo(INTERRUPTED_INTERNAL, DONT_UPDATE_OBSERVERS);
RecordDownloadInterrupted(reason, received_bytes_, total_bytes_);
+ if (!GetWebContents())
+ RecordDownloadCount(INTERRUPTED_WITHOUT_WEBCONTENTS);
AutoResumeIfValid();
UpdateObservers();
diff --git a/content/browser/download/download_item_impl_unittest.cc b/content/browser/download/download_item_impl_unittest.cc
index 7d348372c2..ff5d32602f 100644
--- a/content/browser/download/download_item_impl_unittest.cc
+++ b/content/browser/download/download_item_impl_unittest.cc
@@ -496,7 +496,7 @@ TEST_F(DownloadItemTest, LimitRestartsAfterInterrupted) {
// to be callled, so we simply verify that GetWebContents() is called.
if (i < (DownloadItemImpl::kMaxAutoResumeAttempts - 1)) {
EXPECT_CALL(*mock_request_handle, GetWebContents())
- .WillOnce(Return(static_cast<WebContents*>(NULL)));
+ .WillRepeatedly(Return(static_cast<WebContents*>(NULL)));
}
// Copied key parts of DoIntermediateRename & AddDownloadFileToDownloadItem
diff --git a/content/browser/download/download_manager_impl.cc b/content/browser/download/download_manager_impl.cc
index 47e3aaa494..58fe952217 100644
--- a/content/browser/download/download_manager_impl.cc
+++ b/content/browser/download/download_manager_impl.cc
@@ -524,6 +524,7 @@ void DownloadManagerImpl::OnSavePackageSuccessfullyFinished(
void DownloadManagerImpl::ResumeInterruptedDownload(
scoped_ptr<content::DownloadUrlParameters> params,
uint32 id) {
+ RecordDownloadSource(INITIATED_BY_RESUMPTION);
BrowserThread::PostTask(
BrowserThread::IO,
FROM_HERE,
diff --git a/content/browser/download/download_resource_handler.cc b/content/browser/download/download_resource_handler.cc
index 2a02cf926d..3b4844e6e6 100644
--- a/content/browser/download/download_resource_handler.cc
+++ b/content/browser/download/download_resource_handler.cc
@@ -171,11 +171,10 @@ bool DownloadResourceHandler::OnResponseStarted(
const net::HttpResponseHeaders* headers = request_->response_headers();
if (headers) {
std::string last_modified_hdr;
- std::string etag;
if (headers->EnumerateHeader(NULL, "Last-Modified", &last_modified_hdr))
info->last_modified = last_modified_hdr;
- if (headers->EnumerateHeader(NULL, "ETag", &etag))
- info->etag = etag;
+ if (headers->EnumerateHeader(NULL, "ETag", &etag_))
+ info->etag = etag_;
int status = headers->response_code();
if (2 == status / 100 && status != net::HTTP_PARTIAL_CONTENT) {
@@ -373,7 +372,7 @@ bool DownloadResourceHandler::OnResponseCompleted(
}
}
- RecordAcceptsRanges(accept_ranges_, bytes_read_);
+ RecordAcceptsRanges(accept_ranges_, bytes_read_, etag_);
RecordNetworkBlockage(
base::TimeTicks::Now() - download_start_time_, total_pause_time_);
diff --git a/content/browser/download/download_resource_handler.h b/content/browser/download/download_resource_handler.h
index 866bffb6a9..d38068d548 100644
--- a/content/browser/download/download_resource_handler.h
+++ b/content/browser/download/download_resource_handler.h
@@ -126,6 +126,7 @@ class CONTENT_EXPORT DownloadResourceHandler
size_t last_buffer_size_;
int64 bytes_read_;
std::string accept_ranges_;
+ std::string etag_;
int pause_count_;
bool was_deferred_;
diff --git a/content/browser/download/download_stats.cc b/content/browser/download/download_stats.cc
index c1b251d9a0..f8a1e09f19 100644
--- a/content/browser/download/download_stats.cc
+++ b/content/browser/download/download_stats.cc
@@ -179,7 +179,8 @@ void RecordDownloadWriteLoopCount(int count) {
}
void RecordAcceptsRanges(const std::string& accepts_ranges,
- int64 download_len) {
+ int64 download_len,
+ const std::string& etag) {
int64 max = 1024 * 1024 * 1024; // One Terabyte.
download_len /= 1024; // In Kilobytes
static const int kBuckets = 50;
@@ -196,6 +197,10 @@ void RecordAcceptsRanges(const std::string& accepts_ranges,
1,
max,
kBuckets);
+ // ETags that start with "W/" are considered weak ETags which don't imply
+ // byte-wise equality.
+ if (!StartsWithASCII(etag, "w/", false))
+ RecordDownloadCount(STRONG_ETAG_AND_ACCEPTS_RANGES);
} else {
UMA_HISTOGRAM_CUSTOM_COUNTS("Download.AcceptRangesMissingOrInvalid.KBytes",
download_len,
diff --git a/content/browser/download/download_stats.h b/content/browser/download/download_stats.h
index 287b34d850..be2ae4b567 100644
--- a/content/browser/download/download_stats.h
+++ b/content/browser/download/download_stats.h
@@ -68,6 +68,14 @@ enum DownloadCountTypes {
// successful invocation of ScanAndSaveDownloadedFile().
FILE_MISSING_AFTER_SUCCESSFUL_SCAN_COUNT,
+ // Count of downloads that supplies a strong ETag and has a 'Accept-Ranges:
+ // bytes' header. These downloads are candidates for partial resumption.
+ STRONG_ETAG_AND_ACCEPTS_RANGES,
+
+ // Count of downloads that didn't have a valid WebContents at the time it was
+ // interrupted.
+ INTERRUPTED_WITHOUT_WEBCONTENTS,
+
DOWNLOAD_COUNT_TYPES_LAST_ENTRY
};
@@ -85,6 +93,13 @@ enum DownloadSource {
// (e.g. by Alt-click) through the IPC ViewHostMsg_DownloadUrl.
INITIATED_BY_RENDERER,
+ // Fomerly INITIATED_BY_PEPPER_SAVE.
+ DOWNLOAD_SOURCE_UNUSED_3,
+
+ // A request that was initiated as a result of resuming an interrupted
+ // download.
+ INITIATED_BY_RESUMPTION,
+
DOWNLOAD_SOURCE_LAST_ENTRY
};
@@ -141,8 +156,11 @@ void RecordBandwidth(double actual_bandwidth, double potential_bandwidth);
// download completed.
void RecordOpen(const base::Time& end, bool first);
-// Record whether or not the server accepts ranges, and the download size.
-void RecordAcceptsRanges(const std::string& accepts_ranges, int64 download_len);
+// Record whether or not the server accepts ranges, and the download size. Also
+// counts if a strong ETag is supplied. The combination of range request support
+// and ETag indicates downloads that are candidates for partial resumption.
+void RecordAcceptsRanges(const std::string& accepts_ranges, int64 download_len,
+ const std::string& etag);
// Record the number of downloads removed by ClearAll.
void RecordClearAllSize(int size);
diff --git a/content/browser/download/save_package.cc b/content/browser/download/save_package.cc
index 1d793126b3..a386a2be0c 100644
--- a/content/browser/download/save_package.cc
+++ b/content/browser/download/save_package.cc
@@ -1318,7 +1318,7 @@ void SavePackage::GetSaveInfo() {
// Can't use web_contents_ in the file thread, so get the data that we need
// before calling to it.
base::FilePath website_save_dir, download_save_dir;
- bool skip_dir_check;
+ bool skip_dir_check = false;
DCHECK(download_manager_);
if (download_manager_->GetDelegate()) {
download_manager_->GetDelegate()->GetSaveDir(
diff --git a/content/browser/fileapi/browser_file_system_helper.cc b/content/browser/fileapi/browser_file_system_helper.cc
index 1dac0f6479..e809857f08 100644
--- a/content/browser/fileapi/browser_file_system_helper.cc
+++ b/content/browser/fileapi/browser_file_system_helper.cc
@@ -23,7 +23,6 @@
#include "webkit/browser/fileapi/file_system_backend.h"
#include "webkit/browser/fileapi/file_system_operation_runner.h"
#include "webkit/browser/fileapi/file_system_options.h"
-#include "webkit/browser/fileapi/file_system_task_runners.h"
#include "webkit/browser/quota/quota_manager.h"
namespace content {
@@ -58,11 +57,6 @@ scoped_refptr<fileapi::FileSystemContext> CreateFileSystemContext(
scoped_refptr<base::SequencedTaskRunner> file_task_runner =
pool->GetSequencedTaskRunner(pool->GetNamedSequenceToken("FileAPI"));
- scoped_ptr<fileapi::FileSystemTaskRunners> task_runners(
- new fileapi::FileSystemTaskRunners(
- BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO).get(),
- file_task_runner.get()));
-
// Setting up additional filesystem backends.
ScopedVector<fileapi::FileSystemBackend> additional_backends;
GetContentClient()->browser()->GetAdditionalFileSystemBackends(
@@ -72,7 +66,8 @@ scoped_refptr<fileapi::FileSystemContext> CreateFileSystemContext(
scoped_refptr<fileapi::FileSystemContext> file_system_context =
new fileapi::FileSystemContext(
- task_runners.Pass(),
+ BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO).get(),
+ file_task_runner.get(),
BrowserContext::GetMountPoints(browser_context),
browser_context->GetSpecialStoragePolicy(),
quota_manager_proxy,
@@ -126,7 +121,7 @@ void SyncGetPlatformPath(fileapi::FileSystemContext* context,
int process_id,
const GURL& path,
base::FilePath* platform_path) {
- DCHECK(context->task_runners()->file_task_runner()->
+ DCHECK(context->default_file_task_runner()->
RunsTasksOnCurrentThread());
DCHECK(platform_path);
*platform_path = base::FilePath();
diff --git a/content/browser/fileapi/fileapi_message_filter.cc b/content/browser/fileapi/fileapi_message_filter.cc
index 1fbb338504..cf95b02332 100644
--- a/content/browser/fileapi/fileapi_message_filter.cc
+++ b/content/browser/fileapi/fileapi_message_filter.cc
@@ -29,9 +29,7 @@
#include "webkit/browser/fileapi/file_observers.h"
#include "webkit/browser/fileapi/file_permission_policy.h"
#include "webkit/browser/fileapi/file_system_context.h"
-#include "webkit/browser/fileapi/file_system_task_runners.h"
#include "webkit/browser/fileapi/isolated_context.h"
-#include "webkit/browser/fileapi/local_file_system_operation.h"
#include "webkit/browser/quota/quota_manager.h"
#include "webkit/common/blob/blob_data.h"
#include "webkit/common/blob/shareable_file_reference.h"
@@ -44,7 +42,6 @@ using fileapi::FileSystemBackend;
using fileapi::FileSystemOperation;
using fileapi::FileSystemURL;
using fileapi::FileUpdateObserver;
-using fileapi::LocalFileSystemOperation;
using fileapi::UpdateObserverList;
using webkit_blob::BlobData;
using webkit_blob::BlobStorageController;
@@ -139,7 +136,7 @@ void FileAPIMessageFilter::OnChannelClosing() {
base::TaskRunner* FileAPIMessageFilter::OverrideTaskRunnerForMessage(
const IPC::Message& message) {
if (message.type() == FileSystemHostMsg_SyncGetPlatformPath::ID)
- return context_->task_runners()->file_task_runner();
+ return context_->default_file_task_runner();
return NULL;
}
@@ -720,7 +717,7 @@ void FileAPIMessageFilter::DidCreateSnapshot(
file_ref = webkit_blob::ShareableFileReference::GetOrCreate(
platform_path,
webkit_blob::ShareableFileReference::DONT_DELETE_ON_FINAL_RELEASE,
- context_->task_runners()->file_task_runner());
+ context_->default_file_task_runner());
}
file_ref->AddFinalReleaseCallback(
base::Bind(&RevokeFilePermission, process_id_));
diff --git a/content/browser/gpu/compositor_util.cc b/content/browser/gpu/compositor_util.cc
index a0cf1e21a2..96c626427f 100644
--- a/content/browser/gpu/compositor_util.cc
+++ b/content/browser/gpu/compositor_util.cc
@@ -78,7 +78,7 @@ bool IsThreadedCompositingEnabled() {
}
bool IsForceCompositingModeEnabled() {
-#if defined(OS_WIN) && defined(USE_AURA)
+#if defined(OS_WIN)
// We always want compositing on Aura Windows.
return true;
#endif
diff --git a/content/browser/gpu/gpu_data_manager_impl_private.cc b/content/browser/gpu/gpu_data_manager_impl_private.cc
index 82e4369474..1bd1f6b95d 100644
--- a/content/browser/gpu/gpu_data_manager_impl_private.cc
+++ b/content/browser/gpu/gpu_data_manager_impl_private.cc
@@ -157,11 +157,7 @@ void UpdateStats(const gpu::GpuBlacklist* blacklist,
const bool kGpuFeatureUserFlags[] = {
command_line.HasSwitch(switches::kDisableAccelerated2dCanvas),
command_line.HasSwitch(switches::kDisableAcceleratedCompositing),
-#if defined(OS_ANDROID)
- !command_line.HasSwitch(switches::kEnableExperimentalWebGL),
-#else
command_line.HasSwitch(switches::kDisableExperimentalWebGL),
-#endif
command_line.HasSwitch(switches::kDisableImageTransportSurface)
};
#if defined(OS_WIN)
@@ -266,6 +262,8 @@ void ApplyAndroidWorkarounds(const gpu::GPUInfo& gpu_info,
gpu_info.gl_vendor.find("Broadcom") != std::string::npos;
bool is_mali_t604 = is_arm &&
gpu_info.gl_renderer.find("Mali-T604") != std::string::npos;
+ bool is_nvidia =
+ gpu_info.gl_vendor.find("NVIDIA") != std::string::npos;
bool is_vivante =
gpu_info.gl_extensions.find("GL_VIV_shader_binary") !=
@@ -279,7 +277,7 @@ void ApplyAndroidWorkarounds(const gpu::GPUInfo& gpu_info,
// IMG: avoid context switching perf problems, crashes with share groups
// Mali-T604: http://crbug.com/154715
// QualComm, NVIDIA: Crashes with share groups
- if (is_vivante || is_img || is_mali_t604 || is_nexus7 || is_qualcomm ||
+ if (is_vivante || is_img || is_mali_t604 || is_nvidia || is_qualcomm ||
is_broadcom)
command_line->AppendSwitch(switches::kEnableVirtualGLContexts);
@@ -658,6 +656,17 @@ void GpuDataManagerImplPrivate::AppendRendererCommandLine(
if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE) &&
!command_line->HasSwitch(switches::kDisableAcceleratedVideoDecode))
command_line->AppendSwitch(switches::kDisableAcceleratedVideoDecode);
+
+ if (use_software_compositor_ &&
+ !command_line->HasSwitch(switches::kEnableSoftwareCompositing))
+ command_line->AppendSwitch(switches::kEnableSoftwareCompositing);
+
+#if defined(USE_AURA)
+ if (!CanUseGpuBrowserCompositor()) {
+ command_line->AppendSwitch(switches::kDisableGpuCompositing);
+ command_line->AppendSwitch(switches::kDisablePepper3d);
+ }
+#endif
}
void GpuDataManagerImplPrivate::AppendGpuCommandLine(
@@ -812,6 +821,18 @@ void GpuDataManagerImplPrivate::UpdateRendererWebPrefs(
prefs->accelerated_compositing_for_3d_transforms_enabled = false;
prefs->accelerated_compositing_for_plugins_enabled = false;
}
+
+ if (use_software_compositor_) {
+ prefs->force_compositing_mode = true;
+ prefs->accelerated_compositing_enabled = true;
+ prefs->accelerated_compositing_for_3d_transforms_enabled = true;
+ prefs->accelerated_compositing_for_plugins_enabled = true;
+ }
+
+#if defined(USE_AURA)
+ if (!CanUseGpuBrowserCompositor())
+ prefs->accelerated_2d_canvas_enabled = false;
+#endif
}
gpu::GpuSwitchingOption
@@ -914,7 +935,9 @@ bool GpuDataManagerImplPrivate::IsUsingAcceleratedSurface() const {
#endif
bool GpuDataManagerImplPrivate::CanUseGpuBrowserCompositor() const {
- return !IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING);
+ return !ShouldUseSwiftShader() &&
+ !IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING) &&
+ !IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_FORCE_COMPOSITING_MODE);
}
void GpuDataManagerImplPrivate::BlockDomainFrom3DAPIs(
@@ -963,7 +986,8 @@ GpuDataManagerImplPrivate::GpuDataManagerImplPrivate(
domain_blocking_enabled_(true),
owner_(owner),
display_count_(0),
- gpu_process_accessible_(true) {
+ gpu_process_accessible_(true),
+ use_software_compositor_(false) {
DCHECK(owner_);
CommandLine* command_line = CommandLine::ForCurrentProcess();
if (command_line->HasSwitch(switches::kDisableAcceleratedCompositing)) {
@@ -972,6 +996,8 @@ GpuDataManagerImplPrivate::GpuDataManagerImplPrivate(
}
if (command_line->HasSwitch(switches::kDisableGpu))
DisableHardwareAcceleration();
+ if (command_line->HasSwitch(switches::kEnableSoftwareCompositing))
+ use_software_compositor_ = true;
if (command_line->HasSwitch(switches::kGpuSwitching)) {
std::string option_string = command_line->GetSwitchValueASCII(
switches::kGpuSwitching);
diff --git a/content/browser/gpu/gpu_data_manager_impl_private.h b/content/browser/gpu/gpu_data_manager_impl_private.h
index b4b7805010..eb226e863d 100644
--- a/content/browser/gpu/gpu_data_manager_impl_private.h
+++ b/content/browser/gpu/gpu_data_manager_impl_private.h
@@ -244,6 +244,8 @@ class CONTENT_EXPORT GpuDataManagerImplPrivate {
bool gpu_process_accessible_;
+ bool use_software_compositor_;
+
DISALLOW_COPY_AND_ASSIGN(GpuDataManagerImplPrivate);
};
diff --git a/content/browser/gpu/gpu_internals_ui.cc b/content/browser/gpu/gpu_internals_ui.cc
index cbc2472bd2..0e778c277b 100644
--- a/content/browser/gpu/gpu_internals_ui.cc
+++ b/content/browser/gpu/gpu_internals_ui.cc
@@ -162,6 +162,10 @@ base::DictionaryValue* GpuInfoAsDictionaryValue() {
gpu_info.gl_ws_version));
basic_info->Append(NewDescriptionValuePair("Window system binding extensions",
gpu_info.gl_ws_extensions));
+ std::string reset_strategy =
+ base::StringPrintf("0x%04x", gpu_info.gl_reset_notification_strategy);
+ basic_info->Append(NewDescriptionValuePair(
+ "Reset notification strategy", reset_strategy));
base::DictionaryValue* info = new base::DictionaryValue();
info->Set("basic_info", basic_info);
@@ -249,11 +253,7 @@ base::Value* GetFeatureStatus() {
{
"webgl",
manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_WEBGL),
-#if defined(OS_ANDROID)
- !command_line.HasSwitch(switches::kEnableExperimentalWebGL),
-#else
command_line.HasSwitch(switches::kDisableExperimentalWebGL),
-#endif
"WebGL has been disabled, either via about:flags or command line.",
false
},
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc
index c7b4666d29..892583d3c5 100644
--- a/content/browser/gpu/gpu_process_host.cc
+++ b/content/browser/gpu/gpu_process_host.cc
@@ -1150,6 +1150,7 @@ bool GpuProcessHost::LaunchGpuProcess(const std::string& channel_id) {
switches::kEnableShareGroupAsyncTextureUpload,
switches::kEnableVirtualGLContexts,
switches::kGpuStartupDialog,
+ switches::kGpuSandboxAllowSysVShm,
switches::kLoggingLevel,
switches::kNoSandbox,
switches::kReduceGpuSandbox,
diff --git a/content/browser/gpu/shader_disk_cache.cc b/content/browser/gpu/shader_disk_cache.cc
index 25e616ddf3..fc578bc4bf 100644
--- a/content/browser/gpu/shader_disk_cache.cc
+++ b/content/browser/gpu/shader_disk_cache.cc
@@ -507,15 +507,12 @@ ShaderDiskCache::ShaderDiskCache(const base::FilePath& cache_path)
: cache_available_(false),
host_id_(0),
cache_path_(cache_path),
- is_initialized_(false),
- backend_(NULL) {
+ is_initialized_(false) {
ShaderCacheFactory::GetInstance()->AddToCache(cache_path_, this);
}
ShaderDiskCache::~ShaderDiskCache() {
ShaderCacheFactory::GetInstance()->RemoveFromCache(cache_path_);
- if (backend_)
- delete backend_;
}
void ShaderDiskCache::Init() {
diff --git a/content/browser/gpu/shader_disk_cache.h b/content/browser/gpu/shader_disk_cache.h
index d06434ad98..051be5876e 100644
--- a/content/browser/gpu/shader_disk_cache.h
+++ b/content/browser/gpu/shader_disk_cache.h
@@ -75,7 +75,7 @@ class CONTENT_EXPORT ShaderDiskCache
void CacheCreatedCallback(int rv);
- disk_cache::Backend* backend() { return backend_; }
+ disk_cache::Backend* backend() { return backend_.get(); }
void EntryComplete(void* entry);
void ReadComplete();
@@ -87,7 +87,7 @@ class CONTENT_EXPORT ShaderDiskCache
net::CompletionCallback available_callback_;
net::CompletionCallback cache_complete_callback_;
- disk_cache::Backend* backend_;
+ scoped_ptr<disk_cache::Backend> backend_;
scoped_refptr<ShaderDiskReadHelper> helper_;
std::map<void*, scoped_refptr<ShaderDiskCacheEntry> > entry_map_;
diff --git a/content/browser/gpu/test_support_gpu.gypi b/content/browser/gpu/test_support_gpu.gypi
index f141069dbf..4892e9a38e 100644
--- a/content/browser/gpu/test_support_gpu.gypi
+++ b/content/browser/gpu/test_support_gpu.gypi
@@ -29,7 +29,6 @@
'<(SHARED_INTERMEDIATE_DIR)/content/content_resources.rc',
'<(SHARED_INTERMEDIATE_DIR)/net/net_resources.rc',
'<(SHARED_INTERMEDIATE_DIR)/webkit/blink_resources.rc',
- '<(SHARED_INTERMEDIATE_DIR)/webkit/webkit_chromium_resources.rc',
],
'conditions': [
['win_use_allocator_shim==1', {
diff --git a/content/browser/gpu/webgl_conformance_test.cc b/content/browser/gpu/webgl_conformance_test.cc
index c58653cd63..79f3078283 100644
--- a/content/browser/gpu/webgl_conformance_test.cc
+++ b/content/browser/gpu/webgl_conformance_test.cc
@@ -27,7 +27,6 @@ class WebGLConformanceTest : public ContentBrowserTest {
// Allow privileged WebGL extensions.
command_line->AppendSwitch(switches::kEnablePrivilegedWebGLExtensions);
#if defined(OS_ANDROID)
- command_line->AppendSwitch(switches::kEnableExperimentalWebGL);
command_line->AppendSwitch(
switches::kDisableGestureRequirementForMediaPlayback);
#endif
diff --git a/content/browser/hyphenator/hyphenator_message_filter.cc b/content/browser/hyphenator/hyphenator_message_filter.cc
deleted file mode 100644
index 5e580d82ca..0000000000
--- a/content/browser/hyphenator/hyphenator_message_filter.cc
+++ /dev/null
@@ -1,120 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/base_paths.h"
-#include "base/bind.h"
-#include "base/logging.h"
-#include "base/path_service.h"
-#include "base/strings/string16.h"
-#include "content/browser/hyphenator/hyphenator_message_filter.h"
-#include "content/common/hyphenator_messages.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/content_browser_client.h"
-#include "content/public/browser/render_process_host.h"
-
-namespace content {
-
-namespace {
-
-// A helper function that closes the specified file in the FILE thread. This
-// function may be called after the HyphenatorMessageFilter object that owns the
-// specified file is deleted, i.e. this function must not depend on the object.
-void CloseDictionary(base::PlatformFile file) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
- base::ClosePlatformFile(file);
-}
-
-} // namespace
-
-HyphenatorMessageFilter::HyphenatorMessageFilter(
- RenderProcessHost* render_process_host)
- : render_process_host_(render_process_host),
- dictionary_file_(base::kInvalidPlatformFileValue),
- weak_factory_(this) {
-}
-
-HyphenatorMessageFilter::~HyphenatorMessageFilter() {
- // Post a FILE task that deletes the dictionary file. This message filter is
- // usually deleted on the IO thread, which does not allow file operations.
- if (dictionary_file_ != base::kInvalidPlatformFileValue) {
- BrowserThread::PostTask(
- BrowserThread::FILE,
- FROM_HERE,
- base::Bind(&CloseDictionary, dictionary_file_));
- }
-}
-
-void HyphenatorMessageFilter::SetDictionaryBase(const base::FilePath& base) {
- dictionary_base_ = base;
-}
-
-void HyphenatorMessageFilter::OverrideThreadForMessage(
- const IPC::Message& message,
- BrowserThread::ID* thread) {
- if (message.type() == HyphenatorHostMsg_OpenDictionary::ID)
- *thread = BrowserThread::UI;
-}
-
-bool HyphenatorMessageFilter::OnMessageReceived(
- const IPC::Message& message,
- bool* message_was_ok) {
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP_EX(HyphenatorMessageFilter,
- message,
- *message_was_ok)
- IPC_MESSAGE_HANDLER(HyphenatorHostMsg_OpenDictionary, OnOpenDictionary)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP_EX()
- return handled;
-}
-
-void HyphenatorMessageFilter::OnOpenDictionary(const string16& locale) {
- if (dictionary_file_ != base::kInvalidPlatformFileValue) {
- SendDictionary();
- return;
- }
- BrowserThread::PostTaskAndReply(
- BrowserThread::FILE,
- FROM_HERE,
- base::Bind(&HyphenatorMessageFilter::OpenDictionary, this, locale),
- base::Bind(&HyphenatorMessageFilter::SendDictionary,
- weak_factory_.GetWeakPtr()));
-}
-
-void HyphenatorMessageFilter::OpenDictionary(const string16& locale) {
- DCHECK(dictionary_file_ == base::kInvalidPlatformFileValue);
-
- if (dictionary_base_.empty()) {
- dictionary_base_ =
- GetContentClient()->browser()->GetHyphenDictionaryDirectory();
- }
- std::string rule_file = locale.empty() ? "en-US" : UTF16ToASCII(locale);
-
- // Currently, only en-US is hyphenated. This is a quick fix for
- // http://crbug.com/167122.
- // TODO(groby): The proper fix entails validating if locale is a properly
- // formatted locale string, but knowledge about valid locales currently
- // resides in chrome, not content.
- if (rule_file != "en-US")
- return;
- rule_file.append("-1-0.dic");
- base::FilePath rule_path = dictionary_base_.AppendASCII(rule_file);
- dictionary_file_ = base::CreatePlatformFile(
- rule_path,
- base::PLATFORM_FILE_READ | base::PLATFORM_FILE_OPEN,
- NULL, NULL);
-}
-
-void HyphenatorMessageFilter::SendDictionary() {
- IPC::PlatformFileForTransit file = IPC::InvalidPlatformFileForTransit();
- if (dictionary_file_ != base::kInvalidPlatformFileValue) {
- file = IPC::GetFileHandleForProcess(
- dictionary_file_,
- render_process_host_->GetHandle(),
- false);
- }
- Send(new HyphenatorMsg_SetDictionary(file));
-}
-
-} // namespace content
diff --git a/content/browser/hyphenator/hyphenator_message_filter.h b/content/browser/hyphenator/hyphenator_message_filter.h
deleted file mode 100644
index a5ed21ce40..0000000000
--- a/content/browser/hyphenator/hyphenator_message_filter.h
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_HYPHENATOR_HYPHENATOR_MESSAGE_FILTER_H_
-#define CONTENT_BROWSER_HYPHENATOR_HYPHENATOR_MESSAGE_FILTER_H_
-
-#include "base/compiler_specific.h"
-#include "base/files/file_path.h"
-#include "base/memory/weak_ptr.h"
-#include "base/platform_file.h"
-#include "content/common/content_export.h"
-#include "content/public/browser/browser_message_filter.h"
-
-namespace content {
-class RenderProcessHost;
-
-// This class is a message filter that handles a HyphenatorHost message. When
-// this class receives a HyphenatorHostMsg_OpenDictionary message, it opens the
-// specified dictionary and sends its file handle.
-class CONTENT_EXPORT HyphenatorMessageFilter : public BrowserMessageFilter {
- public:
- explicit HyphenatorMessageFilter(RenderProcessHost* render_process_host);
-
- // Changes the directory that includes dictionary files. This function
- // provides a method that allows applications to change the directory
- // containing hyphenation dictionaries. When a renderer requests a hyphnation
- // dictionary, this class appends a file name (which consists of a locale, a
- // version number, and an extension) and use it as a dictionary file.
- void SetDictionaryBase(const base::FilePath& directory);
-
- // BrowserMessageFilter implementation.
- virtual void OverrideThreadForMessage(
- const IPC::Message& message,
- BrowserThread::ID* thread) OVERRIDE;
- virtual bool OnMessageReceived(const IPC::Message& message,
- bool* message_was_ok) OVERRIDE;
-
- private:
- friend class TestHyphenatorMessageFilter;
-
- virtual ~HyphenatorMessageFilter();
-
- virtual void OnOpenDictionary(const string16& locale);
-
- // Opens a hyphenation dictionary for the specified locale. When this locale
- // is an empty string, this function uses US English ("en-US").
- void OpenDictionary(const string16& locale);
-
- // Sends the hyphenation dictionary file to a renderer in response to its
- // request. If this class cannot open the specified dictionary file, this
- // function sends an IPC::InvalidPlatformFileForTransit value to tell the
- // renderer that a browser cannot open the file.
- void SendDictionary();
-
- // The RenderProcessHost object that owns this filter. This class uses this
- // object to retrieve the process handle used for creating
- // PlatformFileForTransit objects.
- RenderProcessHost* render_process_host_;
-
- // The directory that includes dictionary files. The default value is the
- // directory containing the executable file.
- base::FilePath dictionary_base_;
-
- // A cached dictionary file.
- base::PlatformFile dictionary_file_;
-
- base::WeakPtrFactory<HyphenatorMessageFilter> weak_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(HyphenatorMessageFilter);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_HYPHENATOR_HYPHENATOR_MESSAGE_FILTER_H_
diff --git a/content/browser/hyphenator/hyphenator_message_filter_unittest.cc b/content/browser/hyphenator/hyphenator_message_filter_unittest.cc
deleted file mode 100644
index e62210d995..0000000000
--- a/content/browser/hyphenator/hyphenator_message_filter_unittest.cc
+++ /dev/null
@@ -1,154 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/hyphenator/hyphenator_message_filter.h"
-
-#include "base/base_paths.h"
-#include "base/files/file_path.h"
-#include "base/path_service.h"
-#include "base/strings/string16.h"
-#include "base/strings/utf_string_conversions.h"
-#include "content/common/hyphenator_messages.h"
-#include "content/public/test/mock_render_process_host.h"
-#include "content/public/test/test_browser_context.h"
-#include "ipc/ipc_message_utils.h"
-#include "ipc/ipc_platform_file.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace content {
-
-// A class derived from the HyphenatorMessageFilter class used in unit tests.
-// This class overrides some methods so we can test the HyphenatorMessageFilter
-// class without posting tasks.
-class TestHyphenatorMessageFilter : public HyphenatorMessageFilter {
- public:
- explicit TestHyphenatorMessageFilter(RenderProcessHost* host)
- : HyphenatorMessageFilter(host),
- type_(0),
- file_(base::kInvalidPlatformFileValue) {
- }
-
- const string16& locale() const { return locale_; }
- uint32 type() const { return type_; }
- base::PlatformFile file() const { return file_; }
-
- // BrowserMessageFilter implementation.
- virtual bool Send(IPC::Message* message) OVERRIDE {
- if (message->type() != HyphenatorMsg_SetDictionary::ID)
- return false;
-
- // Read the PlatformFileForTransit object and check if its value is
- // kInvalidPlatformFileValue. Close the incoming file if it is not
- // kInvalidPlatformFileValue to prevent leaving the dictionary file open.
- type_ = message->type();
- PickleIterator iter(*message);
- IPC::PlatformFileForTransit file;
- IPC::ParamTraits<IPC::PlatformFileForTransit>::Read(message, &iter, &file);
- file_ = IPC::PlatformFileForTransitToPlatformFile(file);
- delete message;
- return true;
- }
-
- void SetDictionary(base::PlatformFile file) {
- dictionary_file_ = file;
- }
-
- void Reset() {
- if (dictionary_file_ != base::kInvalidPlatformFileValue) {
- base::ClosePlatformFile(dictionary_file_);
- dictionary_file_ = base::kInvalidPlatformFileValue;
- }
- locale_.clear();
- type_ = 0;
- if (file_ != base::kInvalidPlatformFileValue) {
- base::ClosePlatformFile(file_);
- file_ = base::kInvalidPlatformFileValue;
- }
- }
-
- private:
- virtual ~TestHyphenatorMessageFilter() {
- }
-
- // HyphenatorMessageFilter implementation. This function emulates the
- // original implementation without posting a task.
- virtual void OnOpenDictionary(const string16& locale) OVERRIDE {
- locale_ = locale;
- if (dictionary_file_ == base::kInvalidPlatformFileValue)
- OpenDictionary(locale);
- SendDictionary();
- }
-
- string16 locale_;
- uint32 type_;
- base::PlatformFile file_;
-};
-
-class HyphenatorMessageFilterTest : public testing::Test {
- public:
- HyphenatorMessageFilterTest() {
- context_.reset(new TestBrowserContext);
- host_.reset(new MockRenderProcessHost(context_.get()));
- filter_ = new TestHyphenatorMessageFilter(host_.get());
- }
-
- virtual ~HyphenatorMessageFilterTest() {}
-
- scoped_ptr<TestBrowserContext> context_;
- scoped_ptr<MockRenderProcessHost> host_;
- scoped_refptr<TestHyphenatorMessageFilter> filter_;
-};
-
-// Verifies IPC messages sent by the HyphenatorMessageFilter class when it
-// receives IPC messages (HyphenatorHostMsg_OpenDictionary).
-TEST_F(HyphenatorMessageFilterTest, OpenDictionary) {
- // Send a HyphenatorHostMsg_OpenDictionary message with an invalid locale and
- // verify it sends a HyphenatorMsg_SetDictionary message with an invalid file.
- string16 invalid_locale(ASCIIToUTF16("xx-xx"));
- IPC::Message invalid_message(
- 0, HyphenatorHostMsg_OpenDictionary::ID, IPC::Message::PRIORITY_NORMAL);
- invalid_message.WriteString16(invalid_locale);
-
- bool message_was_ok = false;
- filter_->OnMessageReceived(invalid_message, &message_was_ok);
- EXPECT_TRUE(message_was_ok);
- EXPECT_EQ(invalid_locale, filter_->locale());
- EXPECT_EQ(HyphenatorMsg_SetDictionary::ID, filter_->type());
- EXPECT_EQ(base::kInvalidPlatformFileValue, filter_->file());
-
- filter_->Reset();
-
- // Open a sample dictionary file and attach it to the
- // HyphenatorMessageFilter class so it can return a valid file.
- base::FilePath path;
- PathService::Get(base::DIR_SOURCE_ROOT, &path);
- path = path.Append(FILE_PATH_LITERAL("third_party"));
- path = path.Append(FILE_PATH_LITERAL("hyphen"));
- path = path.Append(FILE_PATH_LITERAL("hyph_en_US.dic"));
- base::PlatformFile file = base::CreatePlatformFile(
- path, base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ,
- NULL, NULL);
- EXPECT_NE(base::kInvalidPlatformFileValue, file);
- filter_->SetDictionary(file);
- file = base::kInvalidPlatformFileValue; // Ownership has been transferred.
-
- // Send a HyphenatorHostMsg_OpenDictionary message with an empty locale and
- // verify it sends a HyphenatorMsg_SetDictionary message with a valid file.
- string16 empty_locale;
- IPC::Message valid_message(
- 0, HyphenatorHostMsg_OpenDictionary::ID, IPC::Message::PRIORITY_NORMAL);
- valid_message.WriteString16(empty_locale);
-
- message_was_ok = false;
- filter_->OnMessageReceived(valid_message, &message_was_ok);
- EXPECT_TRUE(message_was_ok);
- EXPECT_EQ(empty_locale, filter_->locale());
- EXPECT_EQ(HyphenatorMsg_SetDictionary::ID, filter_->type());
- EXPECT_NE(base::kInvalidPlatformFileValue, filter_->file());
-
- // Delete all resources used by this test.
- filter_->Reset();
-}
-
-} // namespace content
diff --git a/content/browser/media/encrypted_media_browsertest.cc b/content/browser/media/encrypted_media_browsertest.cc
index 615fba90af..ce5dc4e6ba 100644
--- a/content/browser/media/encrypted_media_browsertest.cc
+++ b/content/browser/media/encrypted_media_browsertest.cc
@@ -269,8 +269,6 @@ IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, Playback_AudioOnly_MP4) {
// Run only when WV CDM is available.
#if defined(WIDEVINE_CDM_AVAILABLE)
-// See http://crbug.com/237636.
-#if !defined(DISABLE_WIDEVINE_CDM_BROWSERTESTS)
IN_PROC_BROWSER_TEST_F(WVEncryptedMediaTest, Playback_AudioOnly_WebM) {
TestMSESimplePlayback("bear-a-enc_a.webm", kWebMAudioOnly,
kWidevineKeySystem);
@@ -307,7 +305,6 @@ IN_PROC_BROWSER_TEST_F(WVEncryptedMediaTest, Playback_AudioOnly_MP4) {
kWidevineKeySystem);
}
#endif // defined(GOOGLE_CHROME_BUILD) || defined(USE_PROPRIETARY_CODECS)
-#endif // !defined(DISABLE_WIDEVINE_CDM_BROWSERTESTS)
#endif // defined(WIDEVINE_CDM_AVAILABLE)
} // namespace content
diff --git a/content/browser/media/webrtc_browsertest.cc b/content/browser/media/webrtc_browsertest.cc
index 7b3a29cb03..8ab977d63f 100644
--- a/content/browser/media/webrtc_browsertest.cc
+++ b/content/browser/media/webrtc_browsertest.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "base/command_line.h"
+#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/common/content_switches.h"
@@ -16,6 +17,27 @@
#include "base/win/windows_version.h"
#endif
+namespace {
+
+std::string GenerateGetUserMediaCall(int min_width,
+ int max_width,
+ int min_height,
+ int max_height,
+ int min_frame_rate,
+ int max_frame_rate) {
+ return base::StringPrintf(
+ "getUserMedia({video: {mandatory: {minWidth: %d, maxWidth: %d, "
+ "minHeight: %d, maxHeight: %d, minFrameRate: %d, maxFrameRate: %d}, "
+ "optional: []}});",
+ min_width,
+ max_width,
+ min_height,
+ max_height,
+ min_frame_rate,
+ max_frame_rate);
+}
+}
+
namespace content {
class WebrtcBrowserTest: public ContentBrowserTest {
@@ -230,4 +252,34 @@ IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, MANUAL_CallAndModifyStream) {
ExpectTitle("OK");
}
+// This test calls getUserMedia in sequence with different constraints.
+IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, TestGetUserMediaConstraints) {
+ GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
+
+ std::vector<std::string> list_of_get_user_media_calls;
+ list_of_get_user_media_calls.push_back(
+ GenerateGetUserMediaCall(320, 320, 180, 180, 30, 30));
+ list_of_get_user_media_calls.push_back(
+ GenerateGetUserMediaCall(320, 320, 240, 240, 30, 30));
+ list_of_get_user_media_calls.push_back(
+ GenerateGetUserMediaCall(640, 640, 360, 360, 30, 30));
+ list_of_get_user_media_calls.push_back(
+ GenerateGetUserMediaCall(640, 640, 480, 480, 30, 30));
+ list_of_get_user_media_calls.push_back(
+ GenerateGetUserMediaCall(960, 960, 720, 720, 30, 30));
+ list_of_get_user_media_calls.push_back(
+ GenerateGetUserMediaCall(1280, 1280, 720, 720, 30, 30));
+ list_of_get_user_media_calls.push_back(
+ GenerateGetUserMediaCall(1920, 1920, 1080, 1080, 30, 30));
+
+ for (std::vector<std::string>::iterator const_iterator =
+ list_of_get_user_media_calls.begin();
+ const_iterator != list_of_get_user_media_calls.end();
+ ++const_iterator) {
+ DVLOG(1) << "Calling getUserMedia: " << *const_iterator;
+ NavigateToURL(shell(), url);
+ EXPECT_TRUE(ExecuteJavascript(*const_iterator));
+ ExpectTitle("OK");
+ }
+}
} // namespace content
diff --git a/content/browser/power_monitor_message_broadcaster.cc b/content/browser/power_monitor_message_broadcaster.cc
new file mode 100644
index 0000000000..77abcb959f
--- /dev/null
+++ b/content/browser/power_monitor_message_broadcaster.cc
@@ -0,0 +1,39 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/power_monitor_message_broadcaster.h"
+
+#include "base/power_monitor/power_monitor.h"
+#include "content/common/power_monitor_messages.h"
+#include "ipc/ipc_sender.h"
+
+namespace content {
+
+PowerMonitorMessageBroadcaster::PowerMonitorMessageBroadcaster(
+ IPC::Sender* sender)
+ : sender_(sender) {
+ base::PowerMonitor* power_monitor = base::PowerMonitor::Get();
+ if (power_monitor)
+ power_monitor->AddObserver(this);
+}
+
+PowerMonitorMessageBroadcaster::~PowerMonitorMessageBroadcaster() {
+ base::PowerMonitor* power_monitor = base::PowerMonitor::Get();
+ if (power_monitor)
+ power_monitor->RemoveObserver(this);
+}
+
+void PowerMonitorMessageBroadcaster::OnPowerStateChange(bool on_battery_power) {
+ sender_->Send(new PowerMonitorMsg_PowerStateChange(on_battery_power));
+}
+
+void PowerMonitorMessageBroadcaster::OnSuspend() {
+ sender_->Send(new PowerMonitorMsg_Suspend());
+}
+
+void PowerMonitorMessageBroadcaster::OnResume() {
+ sender_->Send(new PowerMonitorMsg_Resume());
+}
+
+} // namespace content \ No newline at end of file
diff --git a/content/browser/power_monitor_message_broadcaster.h b/content/browser/power_monitor_message_broadcaster.h
new file mode 100644
index 0000000000..f0e3a207e2
--- /dev/null
+++ b/content/browser/power_monitor_message_broadcaster.h
@@ -0,0 +1,41 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_POWER_MONITOR_MESSAGE_BROADCASTER_H_
+#define CONTENT_BROWSER_POWER_MONITOR_MESSAGE_BROADCASTER_H_
+
+#include "base/basictypes.h"
+#include "base/memory/ref_counted.h"
+#include "base/power_monitor/power_observer.h"
+#include "content/common/content_export.h"
+#include "content/public/browser/browser_thread.h"
+
+namespace IPC {
+ class Sender;
+}
+
+namespace content {
+
+// A class used to monitor the power state change and communicate it to child
+// processes via IPC.
+class CONTENT_EXPORT PowerMonitorMessageBroadcaster
+ : public base::PowerObserver {
+ public:
+ explicit PowerMonitorMessageBroadcaster(IPC::Sender* sender);
+ virtual ~PowerMonitorMessageBroadcaster();
+
+ // Implement PowerObserver.
+ virtual void OnPowerStateChange(bool on_battery_power) OVERRIDE;
+ virtual void OnSuspend() OVERRIDE;
+ virtual void OnResume() OVERRIDE;
+
+ private:
+ IPC::Sender* sender_;
+
+ DISALLOW_COPY_AND_ASSIGN(PowerMonitorMessageBroadcaster);
+};
+
+} // namespace base
+
+#endif // CONTENT_BROWSER_POWER_MONITOR_MESSAGE_BROADCASTER_H_ \ No newline at end of file
diff --git a/content/browser/power_monitor_message_broadcaster_unittest.cc b/content/browser/power_monitor_message_broadcaster_unittest.cc
new file mode 100644
index 0000000000..6eb0cb4a61
--- /dev/null
+++ b/content/browser/power_monitor_message_broadcaster_unittest.cc
@@ -0,0 +1,109 @@
+// 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 "base/power_monitor/power_monitor_test_base.h"
+#include "content/browser/power_monitor_message_broadcaster.h"
+#include "content/common/power_monitor_messages.h"
+#include "ipc/ipc_sender.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+class PowerMonitorMessageSender : public IPC::Sender {
+ public:
+ PowerMonitorMessageSender()
+ : power_state_changes_(0),
+ suspends_(0),
+ resumes_(0) {
+ }
+ virtual ~PowerMonitorMessageSender() {}
+
+ virtual bool Send(IPC::Message* msg) OVERRIDE {
+ switch (msg->type()) {
+ case PowerMonitorMsg_Suspend::ID:
+ suspends_++;
+ break;
+ case PowerMonitorMsg_Resume::ID:
+ resumes_++;
+ break;
+ case PowerMonitorMsg_PowerStateChange::ID:
+ power_state_changes_++;
+ break;
+ }
+ delete msg;
+ return true;
+ };
+
+ // Test status counts.
+ int power_state_changes() { return power_state_changes_; }
+ int suspends() { return suspends_; }
+ int resumes() { return resumes_; }
+
+ private:
+ int power_state_changes_; // Count of OnPowerStateChange notifications.
+ int suspends_; // Count of OnSuspend notifications.
+ int resumes_; // Count of OnResume notifications.
+};
+
+class PowerMonitorMessageBroadcasterTest : public testing::Test {
+ protected:
+ PowerMonitorMessageBroadcasterTest() {
+ power_monitor_source_ = new base::PowerMonitorTestSource();
+ power_monitor_.reset(new base::PowerMonitor(
+ scoped_ptr<base::PowerMonitorSource>(power_monitor_source_)));
+ }
+ virtual ~PowerMonitorMessageBroadcasterTest() {};
+
+ base::PowerMonitorTestSource* source() { return power_monitor_source_; }
+ base::PowerMonitor* monitor() { return power_monitor_.get(); }
+
+ private:
+ base::PowerMonitorTestSource* power_monitor_source_;
+ scoped_ptr<base::PowerMonitor> power_monitor_;
+
+ DISALLOW_COPY_AND_ASSIGN(PowerMonitorMessageBroadcasterTest);
+};
+
+TEST_F(PowerMonitorMessageBroadcasterTest, PowerMessageBroadcast) {
+ PowerMonitorMessageSender sender;
+ PowerMonitorMessageBroadcaster broadcaster(&sender);
+
+ // Sending resume when not suspended should have no effect.
+ source()->GenerateResumeEvent();
+ EXPECT_EQ(sender.resumes(), 0);
+
+ // Pretend we suspended.
+ source()->GenerateSuspendEvent();
+ EXPECT_EQ(sender.suspends(), 1);
+
+ // Send a second suspend notification. This should be suppressed.
+ source()->GenerateSuspendEvent();
+ EXPECT_EQ(sender.suspends(), 1);
+
+ // Pretend we were awakened.
+ source()->GenerateResumeEvent();
+ EXPECT_EQ(sender.resumes(), 1);
+
+ // Send a duplicate resume notification. This should be suppressed.
+ source()->GenerateResumeEvent();
+ EXPECT_EQ(sender.resumes(), 1);
+
+ // Pretend the device has gone on battery power
+ source()->GeneratePowerStateEvent(true);
+ EXPECT_EQ(sender.power_state_changes(), 1);
+
+ // Repeated indications the device is on battery power should be suppressed.
+ source()->GeneratePowerStateEvent(true);
+ EXPECT_EQ(sender.power_state_changes(), 1);
+
+ // Pretend the device has gone off battery power
+ source()->GeneratePowerStateEvent(false);
+ EXPECT_EQ(sender.power_state_changes(), 2);
+
+ // Repeated indications the device is off battery power should be suppressed.
+ source()->GeneratePowerStateEvent(false);
+ EXPECT_EQ(sender.power_state_changes(), 2);
+}
+
+} // namespace base
diff --git a/content/browser/renderer_host/DEPS b/content/browser/renderer_host/DEPS
index 363a59c139..34decdb022 100644
--- a/content/browser/renderer_host/DEPS
+++ b/content/browser/renderer_host/DEPS
@@ -24,6 +24,7 @@ specific_include_rules = {
"+media/filters",
],
"render_sandbox_host_linux\.cc": [
- "+third_party/WebKit/public/web/WebKit.h"
+ "+third_party/WebKit/public/web/WebKit.h",
+ "+third_party/WebKit/public/web/linux/WebFontInfo.h",
],
}
diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc
index 086b8b2a0c..94ab1393c8 100644
--- a/content/browser/renderer_host/compositor_impl_android.cc
+++ b/content/browser/renderer_host/compositor_impl_android.cc
@@ -358,7 +358,8 @@ bool CompositorImpl::CopyTextureToBitmap(WebKit::WebGLId texture_id,
return true;
}
-scoped_ptr<cc::OutputSurface> CompositorImpl::CreateOutputSurface() {
+scoped_ptr<cc::OutputSurface> CompositorImpl::CreateOutputSurface(
+ bool fallback) {
WebKit::WebGraphicsContext3D::Attributes attrs;
attrs.shareResources = true;
attrs.noAutomaticFlushes = true;
diff --git a/content/browser/renderer_host/compositor_impl_android.h b/content/browser/renderer_host/compositor_impl_android.h
index ba004f9d01..845e830aad 100644
--- a/content/browser/renderer_host/compositor_impl_android.h
+++ b/content/browser/renderer_host/compositor_impl_android.h
@@ -77,7 +77,8 @@ class CONTENT_EXPORT CompositorImpl
virtual void Layout() OVERRIDE {}
virtual void ApplyScrollAndScale(gfx::Vector2d scroll_delta,
float page_scale) OVERRIDE {}
- virtual scoped_ptr<cc::OutputSurface> CreateOutputSurface() OVERRIDE;
+ virtual scoped_ptr<cc::OutputSurface> CreateOutputSurface(bool fallback)
+ OVERRIDE;
virtual void DidInitializeOutputSurface(bool success) OVERRIDE {}
virtual void WillCommit() OVERRIDE {}
virtual void DidCommit() OVERRIDE {}
diff --git a/content/browser/renderer_host/file_utilities_message_filter.cc b/content/browser/renderer_host/file_utilities_message_filter.cc
index bae1079a7d..65645e014e 100644
--- a/content/browser/renderer_host/file_utilities_message_filter.cc
+++ b/content/browser/renderer_host/file_utilities_message_filter.cc
@@ -29,7 +29,6 @@ bool FileUtilitiesMessageFilter::OnMessageReceived(const IPC::Message& message,
bool handled = true;
IPC_BEGIN_MESSAGE_MAP_EX(FileUtilitiesMessageFilter, message, *message_was_ok)
IPC_MESSAGE_HANDLER(FileUtilitiesMsg_GetFileInfo, OnGetFileInfo)
- IPC_MESSAGE_HANDLER(FileUtilitiesMsg_OpenFile, OnOpenFile)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
@@ -53,41 +52,4 @@ void FileUtilitiesMessageFilter::OnGetFileInfo(
*status = base::PLATFORM_FILE_ERROR_FAILED;
}
-void FileUtilitiesMessageFilter::OnOpenFile(
- const base::FilePath& path,
- int mode,
- IPC::PlatformFileForTransit* result) {
- // Open the file only when the child process has been granted permission to
- // upload the file.
- // TODO(jianli): Do we need separate permission to control opening the file?
- if (!ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
- process_id_, path)) {
-#if defined(OS_WIN)
- *result = base::kInvalidPlatformFileValue;
-#elif defined(OS_POSIX)
- *result = base::FileDescriptor(base::kInvalidPlatformFileValue, true);
-#endif
- return;
- }
-
- base::PlatformFile file_handle = base::CreatePlatformFile(
- path,
- (mode == 0) ? (base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ)
- : (base::PLATFORM_FILE_CREATE_ALWAYS |
- base::PLATFORM_FILE_WRITE),
- NULL, NULL);
-
-#if defined(OS_WIN)
- // Duplicate the file handle so that the renderer process can access the file.
- if (!DuplicateHandle(GetCurrentProcess(), file_handle,
- PeerHandle(), result, 0, false,
- DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) {
- // file_handle is closed whether or not DuplicateHandle succeeds.
- *result = INVALID_HANDLE_VALUE;
- }
-#else
- *result = base::FileDescriptor(file_handle, true);
-#endif
-}
-
} // namespace content
diff --git a/content/browser/renderer_host/file_utilities_message_filter.h b/content/browser/renderer_host/file_utilities_message_filter.h
index 1b5640a0d7..948e6c20b4 100644
--- a/content/browser/renderer_host/file_utilities_message_filter.h
+++ b/content/browser/renderer_host/file_utilities_message_filter.h
@@ -39,9 +39,6 @@ class FileUtilitiesMessageFilter : public BrowserMessageFilter {
void OnGetFileInfo(const base::FilePath& path,
base::PlatformFileInfo* result,
base::PlatformFileError* status);
- void OnOpenFile(const base::FilePath& path,
- int mode,
- IPC::PlatformFileForTransit* result);
// The ID of this process.
int process_id_;
diff --git a/content/browser/renderer_host/input/touch_event_queue.cc b/content/browser/renderer_host/input/touch_event_queue.cc
index 0a7b1d4fd9..56500e60fe 100644
--- a/content/browser/renderer_host/input/touch_event_queue.cc
+++ b/content/browser/renderer_host/input/touch_event_queue.cc
@@ -188,12 +188,13 @@ void TouchEventQueue::PopTouchEventWithAck(InputEventAckState ack_result) {
// to the renderer, or touch-events being queued.
base::AutoReset<bool> dispatching_touch_ack(&dispatching_touch_ack_, true);
+ base::TimeTicks now = base::TimeTicks::HighResNow();
for (WebTouchEventWithLatencyList::const_iterator iter = acked_event->begin(),
end = acked_event->end();
iter != end; ++iter) {
ui::LatencyInfo* latency = const_cast<ui::LatencyInfo*>(&(iter->latency));
- latency->AddLatencyNumber(
- ui::INPUT_EVENT_LATENCY_ACKED_COMPONENT, 0, 0);
+ latency->AddLatencyNumberWithTimestamp(
+ ui::INPUT_EVENT_LATENCY_ACKED_COMPONENT, 0, 0, now, 1);
client_->OnTouchEventAck((*iter), ack_result);
}
}
diff --git a/content/browser/renderer_host/java/DEPS b/content/browser/renderer_host/java/DEPS
index 430199d518..0551243588 100644
--- a/content/browser/renderer_host/java/DEPS
+++ b/content/browser/renderer_host/java/DEPS
@@ -1,3 +1,4 @@
include_rules = [
"+content/child", # For java bridge bindings
+ "+third_party/WebKit/public/web/WebBindings.h", # For java bridge bindings
]
diff --git a/content/browser/renderer_host/media/audio_input_renderer_host.cc b/content/browser/renderer_host/media/audio_input_renderer_host.cc
index 4a2f731a81..37d93ef8ca 100644
--- a/content/browser/renderer_host/media/audio_input_renderer_host.cc
+++ b/content/browser/renderer_host/media/audio_input_renderer_host.cc
@@ -15,6 +15,10 @@
#include "content/browser/renderer_host/media/web_contents_capture_util.h"
#include "media/audio/audio_manager_base.h"
+#if defined(USE_CRAS)
+#include "media/audio/cras/audio_manager_cras.h"
+#endif
+
namespace content {
struct AudioInputRendererHost::AudioEntry {
@@ -237,7 +241,18 @@ void AudioInputRendererHost::OnCreateStream(
return;
}
- device_id = info->device.id;
+ if (info->device.type == content::MEDIA_SYSTEM_AUDIO_CAPTURE) {
+#if defined(USE_CRAS)
+ // Use the special loopback device ID for system audio capture.
+ device_id = media::AudioManagerCras::kLoopbackDeviceId;
+#else
+ SendErrorMessage(stream_id);
+ DLOG(WARNING) << "Loopback device is not supported on this platform";
+ return;
+#endif
+ } else {
+ device_id = info->device.id;
+ }
}
// Create a new AudioEntry structure.
diff --git a/content/browser/renderer_host/media/media_stream_manager.cc b/content/browser/renderer_host/media/media_stream_manager.cc
index 3e322c5a43..e4e46b5ac9 100644
--- a/content/browser/renderer_host/media/media_stream_manager.cc
+++ b/content/browser/renderer_host/media/media_stream_manager.cc
@@ -265,10 +265,16 @@ std::string MediaStreamManager::GenerateStream(
DCHECK(found_match || translated_video_device_id.empty());
}
- if (options.video_type == MEDIA_SCREEN_VIDEO_CAPTURE) {
- if (options.audio_type != MEDIA_NO_SERVICE) {
+ if (options.video_type == MEDIA_SCREEN_VIDEO_CAPTURE ||
+ options.audio_type == MEDIA_SYSTEM_AUDIO_CAPTURE) {
+ // For screen capture we only support two valid combinations:
+ // (1) screen video capture only, or
+ // (2) screen video capture with system audio capture.
+ if (options.video_type != MEDIA_SCREEN_VIDEO_CAPTURE ||
+ (options.audio_type != MEDIA_NO_SERVICE &&
+ options.audio_type != MEDIA_SYSTEM_AUDIO_CAPTURE)) {
// TODO(sergeyu): Surface error message to the calling JS code.
- LOG(ERROR) << "Audio is not supported for screen capture streams.";
+ LOG(ERROR) << "Invalid screen capture request.";
return std::string();
}
diff --git a/content/browser/renderer_host/media/midi_dispatcher_host.cc b/content/browser/renderer_host/media/midi_dispatcher_host.cc
new file mode 100644
index 0000000000..4771eb58cc
--- /dev/null
+++ b/content/browser/renderer_host/media/midi_dispatcher_host.cc
@@ -0,0 +1,68 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/renderer_host/media/midi_dispatcher_host.h"
+
+#include "base/bind.h"
+#include "content/browser/renderer_host/render_view_host_impl.h"
+#include "content/common/media/midi_messages.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_thread.h"
+#include "url/gurl.h"
+
+namespace content {
+
+MIDIDispatcherHost::MIDIDispatcherHost(int render_process_id,
+ BrowserContext* browser_context)
+ : render_process_id_(render_process_id),
+ browser_context_(browser_context) {
+}
+
+MIDIDispatcherHost::~MIDIDispatcherHost() {
+}
+
+bool MIDIDispatcherHost::OnMessageReceived(const IPC::Message& message,
+ bool* message_was_ok) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP_EX(MIDIDispatcherHost, message, *message_was_ok)
+ IPC_MESSAGE_HANDLER(MIDIHostMsg_RequestSysExPermission,
+ OnRequestSysExPermission)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP_EX()
+ return handled;
+}
+
+void MIDIDispatcherHost::OverrideThreadForMessage(
+ const IPC::Message& message, BrowserThread::ID* thread) {
+ if (message.type() == MIDIHostMsg_RequestSysExPermission::ID)
+ *thread = BrowserThread::UI;
+}
+
+void MIDIDispatcherHost::OnRequestSysExPermission(int render_view_id,
+ int client_id,
+ const GURL& origin) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ browser_context_->RequestMIDISysExPermission(
+ render_process_id_,
+ render_view_id,
+ origin,
+ base::Bind(&MIDIDispatcherHost::WasSysExPermissionGranted,
+ base::Unretained(this),
+ render_view_id,
+ client_id));
+}
+
+void MIDIDispatcherHost::WasSysExPermissionGranted(int render_view_id,
+ int client_id,
+ bool success) {
+ RenderViewHostImpl* r =
+ RenderViewHostImpl::FromID(render_process_id_, render_view_id);
+ if (!r)
+ return;
+ r->Send(
+ new MIDIMsg_SysExPermissionApproved(render_view_id, client_id, success));
+}
+
+} // namespace content
diff --git a/content/browser/renderer_host/media/midi_dispatcher_host.h b/content/browser/renderer_host/media/midi_dispatcher_host.h
new file mode 100644
index 0000000000..ee861551b4
--- /dev/null
+++ b/content/browser/renderer_host/media/midi_dispatcher_host.h
@@ -0,0 +1,48 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_MIDI_DISPATCHER_HOST_H_
+#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_MIDI_DISPATCHER_HOST_H_
+
+#include "content/public/browser/browser_message_filter.h"
+
+class GURL;
+
+namespace content {
+
+class BrowserContext;
+
+// MIDIDispatcherHost handles permissions for using system exclusive messages.
+// It works as BrowserMessageFilter to handle IPC messages between
+// MIDIDispatcher running as a RenderViewObserver.
+class MIDIDispatcherHost : public BrowserMessageFilter {
+ public:
+ MIDIDispatcherHost(int render_process_id, BrowserContext* browser_context);
+
+ // BrowserMessageFilter implementation.
+ virtual bool OnMessageReceived(const IPC::Message& message,
+ bool* message_was_ok) OVERRIDE;
+ virtual void OverrideThreadForMessage(
+ const IPC::Message& message, BrowserThread::ID* thread) OVERRIDE;
+
+ protected:
+ virtual ~MIDIDispatcherHost();
+
+ private:
+ void OnRequestSysExPermission(int render_view_id,
+ int client_id,
+ const GURL& origin);
+ void WasSysExPermissionGranted(int render_view_id,
+ int client_id,
+ bool success);
+
+ int render_process_id_;
+ BrowserContext* browser_context_;
+
+ DISALLOW_COPY_AND_ASSIGN(MIDIDispatcherHost);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_RENDERER_HOST_MEDIA_MIDI_DISPATCHER_HOST_H_
diff --git a/content/browser/renderer_host/media/midi_host.cc b/content/browser/renderer_host/media/midi_host.cc
index aeb481c05c..6ed473afef 100644
--- a/content/browser/renderer_host/media/midi_host.cc
+++ b/content/browser/renderer_host/media/midi_host.cc
@@ -18,10 +18,24 @@
using media::MIDIManager;
using media::MIDIPortInfoList;
+// The total number of bytes which we're allowed to send to the OS
+// before knowing that they have been successfully sent.
+static const size_t kMaxInFlightBytes = 10 * 1024 * 1024; // 10 MB.
+
+// We keep track of the number of bytes successfully sent to
+// the hardware. Every once in a while we report back to the renderer
+// the number of bytes sent since the last report. This threshold determines
+// how many bytes will be sent before reporting back to the renderer.
+static const size_t kAcknowledgementThresholdBytes = 1024 * 1024; // 1 MB.
+
+static const uint8 kSysExMessage = 0xf0;
+
namespace content {
MIDIHost::MIDIHost(media::MIDIManager* midi_manager)
- : midi_manager_(midi_manager) {
+ : midi_manager_(midi_manager),
+ sent_bytes_in_flight_(0),
+ bytes_sent_since_last_acknowledgement_(0) {
}
MIDIHost::~MIDIHost() {
@@ -77,11 +91,38 @@ void MIDIHost::OnStartSession(int client_id) {
void MIDIHost::OnSendData(int port,
const std::vector<uint8>& data,
double timestamp) {
- // TODO(crogers): we need to post this to a dedicated thread for
- // sending MIDI. For now, we will not implement the sending of MIDI data.
+ if (!midi_manager_)
+ return;
+
+ base::AutoLock auto_lock(in_flight_lock_);
+
+ // Sanity check that we won't send too much.
+ if (sent_bytes_in_flight_ > kMaxInFlightBytes ||
+ data.size() > kMaxInFlightBytes ||
+ data.size() + sent_bytes_in_flight_ > kMaxInFlightBytes)
+ return;
+
+ // For now disallow all System Exclusive messages even if we
+ // have permission.
+ // TODO(toyoshim): allow System Exclusive if browser has granted
+ // this client access. We'll likely need to pass a GURL
+ // here to compare against our permissions.
+ if (data.size() > 0 && data[0] >= kSysExMessage)
+ return;
+
+#if defined(OS_ANDROID)
+ // TODO(toyoshim): figure out why data() method does not compile on Android.
NOTIMPLEMENTED();
- // if (midi_manager_)
- // midi_manager_->SendMIDIData(port, data.data(), data.size(), timestamp);
+#else
+ midi_manager_->DispatchSendMIDIData(
+ this,
+ port,
+ data.data(),
+ data.size(),
+ timestamp);
+#endif
+
+ sent_bytes_in_flight_ += data.size();
}
void MIDIHost::ReceiveMIDIData(
@@ -90,9 +131,37 @@ void MIDIHost::ReceiveMIDIData(
size_t length,
double timestamp) {
TRACE_EVENT0("midi", "MIDIHost::ReceiveMIDIData");
+
+ // For now disallow all System Exclusive messages even if we
+ // have permission.
+ // TODO(toyoshim): allow System Exclusive if browser has granted
+ // this client access. We'll likely need to pass a GURL
+ // here to compare against our permissions.
+ if (length > 0 && data[0] >= kSysExMessage)
+ return;
+
// Send to the renderer.
std::vector<uint8> v(data, data + length);
Send(new MIDIMsg_DataReceived(port_index, v, timestamp));
}
+void MIDIHost::AccumulateMIDIBytesSent(size_t n) {
+ {
+ base::AutoLock auto_lock(in_flight_lock_);
+ if (n <= sent_bytes_in_flight_)
+ sent_bytes_in_flight_ -= n;
+ }
+
+ if (bytes_sent_since_last_acknowledgement_ + n >=
+ bytes_sent_since_last_acknowledgement_)
+ bytes_sent_since_last_acknowledgement_ += n;
+
+ if (bytes_sent_since_last_acknowledgement_ >=
+ kAcknowledgementThresholdBytes) {
+ Send(new MIDIMsg_AcknowledgeSentData(
+ bytes_sent_since_last_acknowledgement_));
+ bytes_sent_since_last_acknowledgement_ = 0;
+ }
+}
+
} // namespace content
diff --git a/content/browser/renderer_host/media/midi_host.h b/content/browser/renderer_host/media/midi_host.h
index db9d937dc8..f6b2813264 100644
--- a/content/browser/renderer_host/media/midi_host.h
+++ b/content/browser/renderer_host/media/midi_host.h
@@ -37,6 +37,7 @@ class CONTENT_EXPORT MIDIHost
const uint8* data,
size_t length,
double timestamp) OVERRIDE;
+ virtual void AccumulateMIDIBytesSent(size_t n) OVERRIDE;
// Start session to access MIDI hardware.
void OnStartSession(int client_id);
@@ -52,8 +53,24 @@ class CONTENT_EXPORT MIDIHost
virtual ~MIDIHost();
+ // |midi_manager_| talks to the platform-specific MIDI APIs.
+ // It can be NULL if the platform (or our current implementation)
+ // does not support MIDI. If not supported then a call to
+ // OnRequestAccess() will always refuse access and a call to
+ // OnSendData() will do nothing.
media::MIDIManager* const midi_manager_;
+ // The number of bytes sent to the platform-specific MIDI sending
+ // system, but not yet completed.
+ size_t sent_bytes_in_flight_;
+
+ // The number of bytes successfully sent since the last time
+ // we've acknowledged back to the renderer.
+ size_t bytes_sent_since_last_acknowledgement_;
+
+ // Protects access to |sent_bytes_in_flight_|.
+ base::Lock in_flight_lock_;
+
DISALLOW_COPY_AND_ASSIGN(MIDIHost);
};
diff --git a/content/browser/renderer_host/media/screen_capture_device.cc b/content/browser/renderer_host/media/screen_capture_device.cc
index e455c48f06..3edd6ccd91 100644
--- a/content/browser/renderer_host/media/screen_capture_device.cc
+++ b/content/browser/renderer_host/media/screen_capture_device.cc
@@ -359,10 +359,13 @@ void ScreenCaptureDevice::SetScreenCapturerForTest(
core_->SetScreenCapturerForTest(capturer.Pass());
}
-void ScreenCaptureDevice::Allocate(int width, int height,
- int frame_rate,
- EventHandler* event_handler) {
- core_->Allocate(width, height, frame_rate, event_handler);
+void ScreenCaptureDevice::Allocate(
+ const media::VideoCaptureCapability& capture_format,
+ EventHandler* observer) {
+ core_->Allocate(capture_format.width,
+ capture_format.height,
+ capture_format.frame_rate,
+ observer);
}
void ScreenCaptureDevice::Start() {
diff --git a/content/browser/renderer_host/media/screen_capture_device.h b/content/browser/renderer_host/media/screen_capture_device.h
index c8b47aab78..df338d7219 100644
--- a/content/browser/renderer_host/media/screen_capture_device.h
+++ b/content/browser/renderer_host/media/screen_capture_device.h
@@ -33,9 +33,8 @@ class CONTENT_EXPORT ScreenCaptureDevice : public media::VideoCaptureDevice {
scoped_ptr<webrtc::ScreenCapturer> capturer);
// VideoCaptureDevice interface.
- virtual void Allocate(int width, int height,
- int frame_rate,
- EventHandler* event_handler) OVERRIDE;
+ virtual void Allocate(const media::VideoCaptureCapability& capture_format,
+ EventHandler* observer) OVERRIDE;
virtual void Start() OVERRIDE;
virtual void Stop() OVERRIDE;
virtual void DeAllocate() OVERRIDE;
diff --git a/content/browser/renderer_host/media/screen_capture_device_unittest.cc b/content/browser/renderer_host/media/screen_capture_device_unittest.cc
index 224c872a7f..c3ca06f8bb 100644
--- a/content/browser/renderer_host/media/screen_capture_device_unittest.cc
+++ b/content/browser/renderer_host/media/screen_capture_device_unittest.cc
@@ -120,7 +120,15 @@ TEST_F(ScreenCaptureDeviceTest, MAYBE_Capture) {
SaveArg<1>(&frame_size),
InvokeWithoutArgs(&done_event, &base::WaitableEvent::Signal)));
- capture_device.Allocate(640, 480, kFrameRate, &frame_observer);
+ media::VideoCaptureCapability capture_format(
+ 640,
+ 480,
+ kFrameRate,
+ media::VideoCaptureCapability::kI420,
+ 0,
+ false,
+ media::ConstantResolutionVideoCaptureDevice);
+ capture_device.Allocate(capture_format, &frame_observer);
capture_device.Start();
EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout()));
capture_device.Stop();
@@ -158,8 +166,15 @@ TEST_F(ScreenCaptureDeviceTest, ScreenResolutionChange) {
SaveArg<1>(&frame_size),
InvokeWithoutArgs(&done_event, &base::WaitableEvent::Signal)));
- capture_device.Allocate(kTestFrameWidth1, kTestFrameHeight1,
- kFrameRate, &frame_observer);
+ media::VideoCaptureCapability capture_format(
+ kTestFrameWidth1,
+ kTestFrameHeight1,
+ kFrameRate,
+ media::VideoCaptureCapability::kI420,
+ 0,
+ false,
+ media::ConstantResolutionVideoCaptureDevice);
+ capture_device.Allocate(capture_format, &frame_observer);
capture_device.Start();
// Capture first frame.
EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout()));
diff --git a/content/browser/renderer_host/media/video_capture_controller.cc b/content/browser/renderer_host/media/video_capture_controller.cc
index feae74a190..bac43289a2 100644
--- a/content/browser/renderer_host/media/video_capture_controller.cc
+++ b/content/browser/renderer_host/media/video_capture_controller.cc
@@ -601,6 +601,8 @@ void VideoCaptureController::DoFrameInfoOnIOThread() {
void VideoCaptureController::DoFrameInfoChangedOnIOThread(
const media::VideoCaptureCapability& info) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ // TODO(mcasas): Here we should reallocate the VideoCaptureBufferPool, if
+ // needed, to support the new video capture format. See crbug.com/266082.
for (ControllerClients::iterator client_it = controller_clients_.begin();
client_it != controller_clients_.end(); ++client_it) {
(*client_it)->event_handler->OnFrameInfoChanged(
@@ -637,11 +639,7 @@ void VideoCaptureController::SendFrameInfoAndBuffers(ControllerClient* client) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
DCHECK(frame_info_available_);
client->event_handler->OnFrameInfo(client->controller_id,
- frame_info_.width, frame_info_.height,
- frame_info_.frame_rate);
- if (!buffer_pool_.get())
- return;
-
+ frame_info_);
for (int buffer_id = 0; buffer_id < buffer_pool_->count(); ++buffer_id) {
base::SharedMemoryHandle remote_handle =
buffer_pool_->ShareToProcess(buffer_id, client->render_process_handle);
diff --git a/content/browser/renderer_host/media/video_capture_controller_event_handler.h b/content/browser/renderer_host/media/video_capture_controller_event_handler.h
index 3d28c44097..c4844af2f7 100644
--- a/content/browser/renderer_host/media/video_capture_controller_event_handler.h
+++ b/content/browser/renderer_host/media/video_capture_controller_event_handler.h
@@ -9,6 +9,10 @@
#include "base/time/time.h"
#include "content/common/content_export.h"
+namespace media {
+struct VideoCaptureCapability;
+}
+
namespace content {
// ID used for identifying an object of VideoCaptureController.
@@ -41,9 +45,7 @@ class CONTENT_EXPORT VideoCaptureControllerEventHandler {
// The frame resolution the VideoCaptureDevice capture video in.
virtual void OnFrameInfo(const VideoCaptureControllerID& id,
- int width,
- int height,
- int frame_rate) = 0;
+ const media::VideoCaptureCapability& format) = 0;
// The frame resolution the VideoCaptureDevice capture video in.
virtual void OnFrameInfoChanged(const VideoCaptureControllerID& id,
diff --git a/content/browser/renderer_host/media/video_capture_controller_unittest.cc b/content/browser/renderer_host/media/video_capture_controller_unittest.cc
index 58b9564b7a..c4b716d2e3 100644
--- a/content/browser/renderer_host/media/video_capture_controller_unittest.cc
+++ b/content/browser/renderer_host/media/video_capture_controller_unittest.cc
@@ -78,10 +78,9 @@ class MockVideoCaptureControllerEventHandler
base::Bind(&VideoCaptureController::ReturnBuffer,
controller_, controller_id_, this, buffer_id));
}
- virtual void OnFrameInfo(const VideoCaptureControllerID& id,
- int width,
- int height,
- int frame_per_second) OVERRIDE {
+ virtual void OnFrameInfo(
+ const VideoCaptureControllerID& id,
+ const media::VideoCaptureCapability& format) OVERRIDE {
EXPECT_EQ(id, controller_id_);
DoFrameInfo(id);
}
@@ -115,9 +114,17 @@ class MockVideoCaptureManager : public VideoCaptureManager {
void Start(const media::VideoCaptureParams& capture_params,
media::VideoCaptureDevice::EventHandler* vc_receiver) OVERRIDE {
StartCapture(capture_params.width, capture_params.height, vc_receiver);
- video_capture_device_->Allocate(capture_params.width, capture_params.height,
- capture_params.frame_per_second,
- vc_receiver);
+ // TODO(mcasas): Add testing for variable resolution video capture devices,
+ // supported by FakeVideoCaptureDevice. See crbug.com/261410, second part.
+ media::VideoCaptureCapability capture_format(
+ capture_params.width,
+ capture_params.height,
+ capture_params.frame_per_second,
+ media::VideoCaptureCapability::kI420,
+ 0,
+ false,
+ media::ConstantResolutionVideoCaptureDevice);
+ video_capture_device_->Allocate(capture_format, vc_receiver);
video_capture_device_->Start();
}
diff --git a/content/browser/renderer_host/media/video_capture_host.cc b/content/browser/renderer_host/media/video_capture_host.cc
index 1d2379d068..bc7c8c19d7 100644
--- a/content/browser/renderer_host/media/video_capture_host.cc
+++ b/content/browser/renderer_host/media/video_capture_host.cc
@@ -83,13 +83,12 @@ void VideoCaptureHost::OnBufferReady(
void VideoCaptureHost::OnFrameInfo(
const VideoCaptureControllerID& controller_id,
- int width,
- int height,
- int frame_per_second) {
+ const media::VideoCaptureCapability& format) {
BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ BrowserThread::IO,
+ FROM_HERE,
base::Bind(&VideoCaptureHost::DoSendFrameInfoOnIOThread,
- this, controller_id, width, height, frame_per_second));
+ this, controller_id, format));
}
void VideoCaptureHost::OnFrameInfoChanged(
@@ -162,18 +161,17 @@ void VideoCaptureHost::DoEndedOnIOThread(
void VideoCaptureHost::DoSendFrameInfoOnIOThread(
const VideoCaptureControllerID& controller_id,
- int width,
- int height,
- int frame_per_second) {
+ const media::VideoCaptureCapability& format) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
if (entries_.find(controller_id) == entries_.end())
return;
media::VideoCaptureParams params;
- params.width = width;
- params.height = height;
- params.frame_per_second = frame_per_second;
+ params.width = format.width;
+ params.height = format.height;
+ params.frame_per_second = format.frame_rate;
+ params.frame_size_type = format.frame_size_type;
Send(new VideoCaptureMsg_DeviceInfo(controller_id.device_id, params));
Send(new VideoCaptureMsg_StateChanged(controller_id.device_id,
VIDEO_CAPTURE_STATE_STARTED));
@@ -216,11 +214,12 @@ void VideoCaptureHost::OnStartCapture(int device_id,
const media::VideoCaptureParams& params) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
DVLOG(1) << "VideoCaptureHost::OnStartCapture, device_id " << device_id
- << ", (" << params.width
- << ", " << params.height
- << ", " << params.frame_per_second
- << ", " << params.session_id
- << ")";
+ << ", (" << params.width << ", " << params.height << ", "
+ << params.frame_per_second << ", " << params.session_id
+ << ", variable resolution device:"
+ << ((params.frame_size_type ==
+ media::VariableResolutionVideoCaptureDevice) ? "yes" : "no")
+ << ")";
VideoCaptureControllerID controller_id(device_id);
DCHECK(entries_.find(controller_id) == entries_.end());
diff --git a/content/browser/renderer_host/media/video_capture_host.h b/content/browser/renderer_host/media/video_capture_host.h
index 3ce428b8a5..025b849de9 100644
--- a/content/browser/renderer_host/media/video_capture_host.h
+++ b/content/browser/renderer_host/media/video_capture_host.h
@@ -45,6 +45,10 @@
#include "content/public/browser/browser_message_filter.h"
#include "ipc/ipc_message.h"
+namespace media {
+struct VideoCaptureCapability;
+}
+
namespace content {
class MediaStreamManager;
@@ -68,10 +72,9 @@ class CONTENT_EXPORT VideoCaptureHost
virtual void OnBufferReady(const VideoCaptureControllerID& id,
int buffer_id,
base::Time timestamp) OVERRIDE;
- virtual void OnFrameInfo(const VideoCaptureControllerID& id,
- int width,
- int height,
- int frame_per_second) OVERRIDE;
+ virtual void OnFrameInfo(
+ const VideoCaptureControllerID& id,
+ const media::VideoCaptureCapability& format) OVERRIDE;
virtual void OnFrameInfoChanged(const VideoCaptureControllerID& id,
int width,
int height,
@@ -122,13 +125,10 @@ class CONTENT_EXPORT VideoCaptureHost
int buffer_id,
base::Time timestamp);
- // Send information about frame resolution and frame rate
+ // Send information about the capture parameters (resolution, frame rate etc)
// to the VideoCaptureMessageFilter.
- void DoSendFrameInfoOnIOThread(
- const VideoCaptureControllerID& controller_id,
- int width,
- int height,
- int frame_per_second);
+ void DoSendFrameInfoOnIOThread(const VideoCaptureControllerID& controller_id,
+ const media::VideoCaptureCapability& format);
// Send newly changed information about frame resolution and frame rate
// to the VideoCaptureMessageFilter.
diff --git a/content/browser/renderer_host/media/video_capture_manager.cc b/content/browser/renderer_host/media/video_capture_manager.cc
index 61574a2626..aa27e12803 100644
--- a/content/browser/renderer_host/media/video_capture_manager.cc
+++ b/content/browser/renderer_host/media/video_capture_manager.cc
@@ -269,6 +269,14 @@ void VideoCaptureManager::OnStart(
video_capture_receiver->OnError();
return;
}
+ // TODO(mcasas): Variable resolution video capture devices, are not yet
+ // fully supported, see crbug.com/261410, second part, and crbug.com/266082 .
+ if (capture_params.frame_size_type !=
+ media::ConstantResolutionVideoCaptureDevice) {
+ LOG(DFATAL) << "Only constant Video Capture resolution device supported.";
+ video_capture_receiver->OnError();
+ return;
+ }
Controllers::iterator cit = controllers_.find(video_capture_device);
if (cit != controllers_.end()) {
cit->second->ready_to_delete = false;
@@ -276,8 +284,13 @@ void VideoCaptureManager::OnStart(
// Possible errors are signaled to video_capture_receiver by
// video_capture_device. video_capture_receiver to perform actions.
- video_capture_device->Allocate(capture_params.width, capture_params.height,
- capture_params.frame_per_second,
+ media::VideoCaptureCapability params_as_capability_copy;
+ params_as_capability_copy.width = capture_params.width;
+ params_as_capability_copy.height = capture_params.height;
+ params_as_capability_copy.frame_rate = capture_params.frame_per_second;
+ params_as_capability_copy.session_id = capture_params.session_id;
+ params_as_capability_copy.frame_size_type = capture_params.frame_size_type;
+ video_capture_device->Allocate(params_as_capability_copy,
video_capture_receiver);
video_capture_device->Start();
}
diff --git a/content/browser/renderer_host/media/web_contents_video_capture_device.cc b/content/browser/renderer_host/media/web_contents_video_capture_device.cc
index 8a6757aa75..2e63e94172 100644
--- a/content/browser/renderer_host/media/web_contents_video_capture_device.cc
+++ b/content/browser/renderer_host/media/web_contents_video_capture_device.cc
@@ -1069,7 +1069,7 @@ void WebContentsVideoCaptureDevice::Impl::Allocate(
// Initialize capture settings which will be consistent for the
// duration of the capture.
- media::VideoCaptureCapability settings = { 0 };
+ media::VideoCaptureCapability settings;
settings.width = width;
settings.height = height;
@@ -1248,9 +1248,14 @@ media::VideoCaptureDevice* WebContentsVideoCaptureDevice::Create(
}
void WebContentsVideoCaptureDevice::Allocate(
- int width, int height, int frame_rate,
- VideoCaptureDevice::EventHandler* consumer) {
- impl_->Allocate(width, height, frame_rate, consumer);
+ const media::VideoCaptureCapability& capture_format,
+ VideoCaptureDevice::EventHandler* observer) {
+ DVLOG(1) << "Allocating " << capture_format.width << "x"
+ << capture_format.height;
+ impl_->Allocate(capture_format.width,
+ capture_format.height,
+ capture_format.frame_rate,
+ observer);
}
void WebContentsVideoCaptureDevice::Start() {
diff --git a/content/browser/renderer_host/media/web_contents_video_capture_device.h b/content/browser/renderer_host/media/web_contents_video_capture_device.h
index 44c1a8f4ba..94ac0680f6 100644
--- a/content/browser/renderer_host/media/web_contents_video_capture_device.h
+++ b/content/browser/renderer_host/media/web_contents_video_capture_device.h
@@ -42,10 +42,8 @@ class CONTENT_EXPORT WebContentsVideoCaptureDevice
virtual ~WebContentsVideoCaptureDevice();
// VideoCaptureDevice implementation.
- virtual void Allocate(int width,
- int height,
- int frame_rate,
- VideoCaptureDevice::EventHandler* consumer) OVERRIDE;
+ virtual void Allocate(const media::VideoCaptureCapability& capture_format,
+ VideoCaptureDevice::EventHandler* observer) OVERRIDE;
virtual void Start() OVERRIDE;
virtual void Stop() OVERRIDE;
virtual void DeAllocate() OVERRIDE;
diff --git a/content/browser/renderer_host/media/web_contents_video_capture_device_unittest.cc b/content/browser/renderer_host/media/web_contents_video_capture_device_unittest.cc
index deb8741ee4..7eb28eac39 100644
--- a/content/browser/renderer_host/media/web_contents_video_capture_device_unittest.cc
+++ b/content/browser/renderer_host/media/web_contents_video_capture_device_unittest.cc
@@ -541,7 +541,15 @@ TEST_F(WebContentsVideoCaptureDeviceTest, InvalidInitialWebContentsError) {
// practice; we should be able to recover gracefully.
ResetWebContents();
- device()->Allocate(kTestWidth, kTestHeight, kTestFramesPerSecond, consumer());
+ media::VideoCaptureCapability capture_format(
+ kTestWidth,
+ kTestHeight,
+ kTestFramesPerSecond,
+ media::VideoCaptureCapability::kI420,
+ 0,
+ false,
+ media::ConstantResolutionVideoCaptureDevice);
+ device()->Allocate(capture_format, consumer());
device()->Start();
ASSERT_NO_FATAL_FAILURE(consumer()->WaitForError());
device()->DeAllocate();
@@ -550,7 +558,15 @@ TEST_F(WebContentsVideoCaptureDeviceTest, InvalidInitialWebContentsError) {
TEST_F(WebContentsVideoCaptureDeviceTest, WebContentsDestroyed) {
// We'll simulate the tab being closed after the capture pipeline is up and
// running.
- device()->Allocate(kTestWidth, kTestHeight, kTestFramesPerSecond, consumer());
+ media::VideoCaptureCapability capture_format(
+ kTestWidth,
+ kTestHeight,
+ kTestFramesPerSecond,
+ media::VideoCaptureCapability::kI420,
+ 0,
+ false,
+ media::ConstantResolutionVideoCaptureDevice);
+ device()->Allocate(capture_format, consumer());
device()->Start();
// Do one capture to prove
@@ -571,7 +587,15 @@ TEST_F(WebContentsVideoCaptureDeviceTest, WebContentsDestroyed) {
TEST_F(WebContentsVideoCaptureDeviceTest,
StopDeviceBeforeCaptureMachineCreation) {
- device()->Allocate(kTestWidth, kTestHeight, kTestFramesPerSecond, consumer());
+ media::VideoCaptureCapability capture_format(
+ kTestWidth,
+ kTestHeight,
+ kTestFramesPerSecond,
+ media::VideoCaptureCapability::kI420,
+ 0,
+ false,
+ media::ConstantResolutionVideoCaptureDevice);
+ device()->Allocate(capture_format, consumer());
device()->Start();
// Make a point of not running the UI messageloop here.
device()->Stop();
@@ -589,8 +613,16 @@ TEST_F(WebContentsVideoCaptureDeviceTest, StopWithRendererWorkToDo) {
// Set up the test to use RGB copies and an normal
source()->SetCanCopyToVideoFrame(false);
source()->SetUseFrameSubscriber(false);
- device()->Allocate(kTestWidth, kTestHeight, kTestFramesPerSecond,
- consumer());
+ media::VideoCaptureCapability capture_format(
+ kTestWidth,
+ kTestHeight,
+ kTestFramesPerSecond,
+ media::VideoCaptureCapability::kI420,
+ 0,
+ false,
+ media::ConstantResolutionVideoCaptureDevice);
+ device()->Allocate(capture_format, consumer());
+
device()->Start();
// Make a point of not running the UI messageloop here.
// TODO(ajwong): Why do we care?
@@ -611,7 +643,15 @@ TEST_F(WebContentsVideoCaptureDeviceTest, StopWithRendererWorkToDo) {
}
TEST_F(WebContentsVideoCaptureDeviceTest, DeviceRestart) {
- device()->Allocate(kTestWidth, kTestHeight, kTestFramesPerSecond, consumer());
+ media::VideoCaptureCapability capture_format(
+ kTestWidth,
+ kTestHeight,
+ kTestFramesPerSecond,
+ media::VideoCaptureCapability::kI420,
+ 0,
+ false,
+ media::ConstantResolutionVideoCaptureDevice);
+ device()->Allocate(capture_format, consumer());
device()->Start();
base::RunLoop().RunUntilIdle();
source()->SetSolidColor(SK_ColorRED);
@@ -645,7 +685,15 @@ TEST_F(WebContentsVideoCaptureDeviceTest, DeviceRestart) {
// consumer. The test will alternate between the three capture paths, simulating
// falling in and out of accelerated compositing.
TEST_F(WebContentsVideoCaptureDeviceTest, GoesThroughAllTheMotions) {
- device()->Allocate(kTestWidth, kTestHeight, kTestFramesPerSecond, consumer());
+ media::VideoCaptureCapability capture_format(
+ kTestWidth,
+ kTestHeight,
+ kTestFramesPerSecond,
+ media::VideoCaptureCapability::kI420,
+ 0,
+ false,
+ media::ConstantResolutionVideoCaptureDevice);
+ device()->Allocate(capture_format, consumer());
device()->Start();
@@ -693,14 +741,33 @@ TEST_F(WebContentsVideoCaptureDeviceTest, GoesThroughAllTheMotions) {
}
TEST_F(WebContentsVideoCaptureDeviceTest, RejectsInvalidAllocateParams) {
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::Bind(&media::VideoCaptureDevice::Allocate,
- base::Unretained(device()), 1280, 720, -2, consumer()));
+ media::VideoCaptureCapability capture_format(
+ 1280,
+ 720,
+ -2,
+ media::VideoCaptureCapability::kI420,
+ 0,
+ false,
+ media::ConstantResolutionVideoCaptureDevice);
+ BrowserThread::PostTask(BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(&media::VideoCaptureDevice::Allocate,
+ base::Unretained(device()),
+ capture_format,
+ consumer()));
ASSERT_NO_FATAL_FAILURE(consumer()->WaitForError());
}
TEST_F(WebContentsVideoCaptureDeviceTest, BadFramesGoodFrames) {
- device()->Allocate(kTestWidth, kTestHeight, kTestFramesPerSecond, consumer());
+ media::VideoCaptureCapability capture_format(
+ kTestWidth,
+ kTestHeight,
+ kTestFramesPerSecond,
+ media::VideoCaptureCapability::kI420,
+ 0,
+ false,
+ media::ConstantResolutionVideoCaptureDevice);
+ device()->Allocate(capture_format, consumer());
// 1x1 is too small to process; we intend for this to result in an error.
source()->SetCopyResultSize(1, 1);
diff --git a/content/browser/renderer_host/pepper/pepper_file_ref_host.cc b/content/browser/renderer_host/pepper/pepper_file_ref_host.cc
index 59d2c08221..5370af9d85 100644
--- a/content/browser/renderer_host/pepper/pepper_file_ref_host.cc
+++ b/content/browser/renderer_host/pepper/pepper_file_ref_host.cc
@@ -53,8 +53,9 @@ PepperFileRefHost::PepperFileRefHost(BrowserPpapiHost* host,
return;
}
- PepperFileSystemBrowserHost* fs_host =
- fs_resource_host->AsPepperFileSystemBrowserHost();
+ PepperFileSystemBrowserHost* fs_host = NULL;
+ if (fs_resource_host->IsFileSystemHost())
+ fs_host = static_cast<PepperFileSystemBrowserHost*>(fs_resource_host);
if (fs_host == NULL) {
DLOG(ERROR) << "Filesystem PP_Resource is not PepperFileSystemBrowserHost";
return;
@@ -101,8 +102,8 @@ PepperFileRefHost::PepperFileRefHost(BrowserPpapiHost* host,
PepperFileRefHost::~PepperFileRefHost() {
}
-PepperFileRefHost* PepperFileRefHost::AsPepperFileRefHost() {
- return this;
+bool PepperFileRefHost::IsFileRefHost() {
+ return true;
}
PP_FileSystemType PepperFileRefHost::GetFileSystemType() const {
@@ -219,7 +220,9 @@ int32_t PepperFileRefHost::OnRename(ppapi::host::HostMessageContext* context,
if (!resource_host)
return PP_ERROR_BADRESOURCE;
- PepperFileRefHost* file_ref_host = resource_host->AsPepperFileRefHost();
+ PepperFileRefHost* file_ref_host = NULL;
+ if (resource_host->IsFileRefHost())
+ file_ref_host = static_cast<PepperFileRefHost*>(resource_host);
if (!file_ref_host)
return PP_ERROR_BADRESOURCE;
diff --git a/content/browser/renderer_host/pepper/pepper_file_ref_host.h b/content/browser/renderer_host/pepper/pepper_file_ref_host.h
index ce742faebf..5d76576432 100644
--- a/content/browser/renderer_host/pepper/pepper_file_ref_host.h
+++ b/content/browser/renderer_host/pepper/pepper_file_ref_host.h
@@ -73,7 +73,7 @@ class CONTENT_EXPORT PepperFileRefHost
virtual int32_t OnResourceMessageReceived(
const IPC::Message& msg,
ppapi::host::HostMessageContext* context) OVERRIDE;
- virtual PepperFileRefHost* AsPepperFileRefHost() OVERRIDE;
+ virtual bool IsFileRefHost() OVERRIDE;
// Required to support Rename().
PP_FileSystemType GetFileSystemType() const;
diff --git a/content/browser/renderer_host/pepper/pepper_file_system_browser_host.cc b/content/browser/renderer_host/pepper/pepper_file_system_browser_host.cc
index 4189741d34..1a10da77b8 100644
--- a/content/browser/renderer_host/pepper/pepper_file_system_browser_host.cc
+++ b/content/browser/renderer_host/pepper/pepper_file_system_browser_host.cc
@@ -84,9 +84,8 @@ int32_t PepperFileSystemBrowserHost::OnResourceMessageReceived(
return PP_ERROR_FAILED;
}
-PepperFileSystemBrowserHost*
-PepperFileSystemBrowserHost::AsPepperFileSystemBrowserHost() {
- return this;
+bool PepperFileSystemBrowserHost::IsFileSystemHost() {
+ return true;
}
int32_t PepperFileSystemBrowserHost::OnHostMsgOpen(
diff --git a/content/browser/renderer_host/pepper/pepper_file_system_browser_host.h b/content/browser/renderer_host/pepper/pepper_file_system_browser_host.h
index 61db917863..3eb146e5b7 100644
--- a/content/browser/renderer_host/pepper/pepper_file_system_browser_host.h
+++ b/content/browser/renderer_host/pepper/pepper_file_system_browser_host.h
@@ -32,7 +32,7 @@ class PepperFileSystemBrowserHost :
virtual int32_t OnResourceMessageReceived(
const IPC::Message& msg,
ppapi::host::HostMessageContext* context) OVERRIDE;
- virtual PepperFileSystemBrowserHost* AsPepperFileSystemBrowserHost() OVERRIDE;
+ virtual bool IsFileSystemHost() OVERRIDE;
// Supports FileRefs direct access on the host side.
PP_FileSystemType GetType() const { return type_; }
diff --git a/content/browser/renderer_host/pepper/pepper_flash_file_message_filter.cc b/content/browser/renderer_host/pepper/pepper_flash_file_message_filter.cc
index 4695386820..ef740625bd 100644
--- a/content/browser/renderer_host/pepper/pepper_flash_file_message_filter.cc
+++ b/content/browser/renderer_host/pepper/pepper_flash_file_message_filter.cc
@@ -9,6 +9,7 @@
#include "base/files/file_enumerator.h"
#include "base/threading/sequenced_worker_pool.h"
#include "content/browser/child_process_security_policy_impl.h"
+#include "content/browser/renderer_host/pepper/pepper_security_helper.h"
#include "content/public/browser/browser_ppapi_host.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_constants.h"
@@ -24,19 +25,24 @@
namespace content {
namespace {
-// Used to check if the renderer has permission for the requested operation.
-// TODO(viettrungluu): Verify these. They don't necessarily quite make sense,
-// but it seems to be approximately what the file system code does.
-const int kReadPermissions = base::PLATFORM_FILE_OPEN |
- base::PLATFORM_FILE_READ |
- base::PLATFORM_FILE_EXCLUSIVE_READ;
-const int kWritePermissions = base::PLATFORM_FILE_OPEN |
- base::PLATFORM_FILE_CREATE |
- base::PLATFORM_FILE_CREATE_ALWAYS |
- base::PLATFORM_FILE_OPEN_TRUNCATED |
- base::PLATFORM_FILE_WRITE |
- base::PLATFORM_FILE_EXCLUSIVE_WRITE |
- base::PLATFORM_FILE_WRITE_ATTRIBUTES;
+
+bool CanRead(int process_id, const base::FilePath& path) {
+ return ChildProcessSecurityPolicyImpl::GetInstance()->
+ CanReadFile(process_id, path);
+}
+
+bool CanWrite(int process_id, const base::FilePath& path) {
+ return ChildProcessSecurityPolicyImpl::GetInstance()->
+ CanWriteFile(process_id, path);
+}
+
+bool CanReadWrite(int process_id, const base::FilePath& path) {
+ ChildProcessSecurityPolicyImpl* policy =
+ ChildProcessSecurityPolicyImpl::GetInstance();
+ return policy->CanReadFile(process_id, path) &&
+ policy->CanWriteFile(process_id, path);
+}
+
} // namespace
PepperFlashFileMessageFilter::PepperFlashFileMessageFilter(
@@ -109,16 +115,24 @@ int32_t PepperFlashFileMessageFilter::OnResourceMessageReceived(
int32_t PepperFlashFileMessageFilter::OnOpenFile(
ppapi::host::HostMessageContext* context,
const ppapi::PepperFilePath& path,
- int flags) {
- base::FilePath full_path = ValidateAndConvertPepperFilePath(path, flags);
+ int pp_open_flags) {
+ base::FilePath full_path = ValidateAndConvertPepperFilePath(
+ path,
+ base::Bind(&CanOpenWithPepperFlags, pp_open_flags));
if (full_path.empty()) {
return ppapi::PlatformFileErrorToPepperError(
base::PLATFORM_FILE_ERROR_ACCESS_DENIED);
}
+ int platform_file_flags = 0;
+ if (!ppapi::PepperFileOpenFlagsToPlatformFileFlags(
+ pp_open_flags, &platform_file_flags)) {
+ return base::PLATFORM_FILE_ERROR_FAILED;
+ }
+
base::PlatformFileError error = base::PLATFORM_FILE_ERROR_FAILED;
base::PlatformFile file_handle = base::CreatePlatformFile(
- full_path, flags, NULL, &error);
+ full_path, platform_file_flags, NULL, &error);
if (error != base::PLATFORM_FILE_OK) {
DCHECK_EQ(file_handle, base::kInvalidPlatformFileValue);
return ppapi::PlatformFileErrorToPepperError(error);
@@ -149,9 +163,9 @@ int32_t PepperFlashFileMessageFilter::OnRenameFile(
const ppapi::PepperFilePath& from_path,
const ppapi::PepperFilePath& to_path) {
base::FilePath from_full_path = ValidateAndConvertPepperFilePath(
- from_path, kWritePermissions);
+ from_path, base::Bind(&CanWrite));
base::FilePath to_full_path = ValidateAndConvertPepperFilePath(
- to_path, kWritePermissions);
+ to_path, base::Bind(&CanWrite));
if (from_full_path.empty() || to_full_path.empty()) {
return ppapi::PlatformFileErrorToPepperError(
base::PLATFORM_FILE_ERROR_ACCESS_DENIED);
@@ -167,7 +181,7 @@ int32_t PepperFlashFileMessageFilter::OnDeleteFileOrDir(
const ppapi::PepperFilePath& path,
bool recursive) {
base::FilePath full_path = ValidateAndConvertPepperFilePath(
- path, kWritePermissions);
+ path, base::Bind(&CanWrite));
if (full_path.empty()) {
return ppapi::PlatformFileErrorToPepperError(
base::PLATFORM_FILE_ERROR_ACCESS_DENIED);
@@ -181,7 +195,7 @@ int32_t PepperFlashFileMessageFilter::OnCreateDir(
ppapi::host::HostMessageContext* context,
const ppapi::PepperFilePath& path) {
base::FilePath full_path = ValidateAndConvertPepperFilePath(
- path, kWritePermissions);
+ path, base::Bind(&CanWrite));
if (full_path.empty()) {
return ppapi::PlatformFileErrorToPepperError(
base::PLATFORM_FILE_ERROR_ACCESS_DENIED);
@@ -196,7 +210,7 @@ int32_t PepperFlashFileMessageFilter::OnQueryFile(
ppapi::host::HostMessageContext* context,
const ppapi::PepperFilePath& path) {
base::FilePath full_path = ValidateAndConvertPepperFilePath(
- path, kReadPermissions);
+ path, base::Bind(&CanRead));
if (full_path.empty()) {
return ppapi::PlatformFileErrorToPepperError(
base::PLATFORM_FILE_ERROR_ACCESS_DENIED);
@@ -213,7 +227,7 @@ int32_t PepperFlashFileMessageFilter::OnGetDirContents(
ppapi::host::HostMessageContext* context,
const ppapi::PepperFilePath& path) {
base::FilePath full_path = ValidateAndConvertPepperFilePath(
- path, kReadPermissions);
+ path, base::Bind(&CanRead));
if (full_path.empty()) {
return ppapi::PlatformFileErrorToPepperError(
base::PLATFORM_FILE_ERROR_ACCESS_DENIED);
@@ -243,7 +257,7 @@ int32_t PepperFlashFileMessageFilter::OnCreateTemporaryFile(
ppapi::PepperFilePath dir_path(
ppapi::PepperFilePath::DOMAIN_MODULE_LOCAL, base::FilePath());
base::FilePath validated_dir_path = ValidateAndConvertPepperFilePath(
- dir_path, kReadPermissions | kWritePermissions);
+ dir_path, base::Bind(&CanReadWrite));
if (validated_dir_path.empty() ||
(!base::DirectoryExists(validated_dir_path) &&
!file_util::CreateDirectory(validated_dir_path))) {
@@ -282,13 +296,13 @@ int32_t PepperFlashFileMessageFilter::OnCreateTemporaryFile(
base::FilePath PepperFlashFileMessageFilter::ValidateAndConvertPepperFilePath(
const ppapi::PepperFilePath& pepper_path,
- int flags) {
+ const CheckPermissionsCallback& check_permissions_callback) const {
base::FilePath file_path; // Empty path returned on error.
switch (pepper_path.domain()) {
case ppapi::PepperFilePath::DOMAIN_ABSOLUTE:
if (pepper_path.path().IsAbsolute() &&
- ChildProcessSecurityPolicyImpl::GetInstance()->HasPermissionsForFile(
- render_process_id_, pepper_path.path(), flags))
+ check_permissions_callback.Run(render_process_id_,
+ pepper_path.path()))
file_path = pepper_path.path();
break;
case ppapi::PepperFilePath::DOMAIN_MODULE_LOCAL:
diff --git a/content/browser/renderer_host/pepper/pepper_flash_file_message_filter.h b/content/browser/renderer_host/pepper/pepper_flash_file_message_filter.h
index 7931764cce..f89d7cf590 100644
--- a/content/browser/renderer_host/pepper/pepper_flash_file_message_filter.h
+++ b/content/browser/renderer_host/pepper/pepper_flash_file_message_filter.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FLASH_FILE_MESSAGE_FILTER_H_
#define CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FLASH_FILE_MESSAGE_FILTER_H_
+#include "base/callback_forward.h"
#include "base/compiler_specific.h"
#include "base/files/file_path.h"
#include "base/memory/ref_counted.h"
@@ -40,6 +41,9 @@ class PepperFlashFileMessageFilter : public ppapi::host::ResourceMessageFilter {
static base::FilePath GetDataDirName(const base::FilePath& profile_path);
private:
+ typedef base::Callback<bool(int, const base::FilePath&)>
+ CheckPermissionsCallback;
+
virtual ~PepperFlashFileMessageFilter();
// ppapi::host::ResourceMessageFilter overrides.
@@ -51,7 +55,7 @@ class PepperFlashFileMessageFilter : public ppapi::host::ResourceMessageFilter {
int32_t OnOpenFile(ppapi::host::HostMessageContext* context,
const ppapi::PepperFilePath& path,
- int flags);
+ int pp_open_flags);
int32_t OnRenameFile(ppapi::host::HostMessageContext* context,
const ppapi::PepperFilePath& from_path,
const ppapi::PepperFilePath& to_path);
@@ -68,7 +72,7 @@ class PepperFlashFileMessageFilter : public ppapi::host::ResourceMessageFilter {
base::FilePath ValidateAndConvertPepperFilePath(
const ppapi::PepperFilePath& pepper_path,
- int flags);
+ const CheckPermissionsCallback& check_permissions_callback) const;
base::FilePath plugin_data_directory_;
int render_process_id_;
diff --git a/content/browser/renderer_host/pepper/pepper_internal_file_ref_backend.h b/content/browser/renderer_host/pepper/pepper_internal_file_ref_backend.h
index dce7889466..fb8a6cf760 100644
--- a/content/browser/renderer_host/pepper/pepper_internal_file_ref_backend.h
+++ b/content/browser/renderer_host/pepper/pepper_internal_file_ref_backend.h
@@ -18,6 +18,8 @@
namespace content {
+class PepperFileSystemBrowserHost;
+
// Implementations of FileRef operations for internal filesystems.
class PepperInternalFileRefBackend : public PepperFileRefBackend {
public:
diff --git a/content/browser/renderer_host/pepper/pepper_renderer_connection.cc b/content/browser/renderer_host/pepper/pepper_renderer_connection.cc
index 8703bed9fa..55b5ab6e7e 100644
--- a/content/browser/renderer_host/pepper/pepper_renderer_connection.cc
+++ b/content/browser/renderer_host/pepper/pepper_renderer_connection.cc
@@ -7,6 +7,8 @@
#include "content/browser/browser_child_process_host_impl.h"
#include "content/browser/ppapi_plugin_process_host.h"
#include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h"
+#include "content/common/pepper_renderer_instance_data.h"
+#include "content/common/view_messages.h"
#include "content/browser/renderer_host/pepper/pepper_file_ref_host.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/common/content_client.h"
@@ -16,12 +18,24 @@
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/proxy/resource_message_params.h"
-#include "content/common/view_messages.h"
-
namespace content {
-namespace {
-BrowserPpapiHostImpl* GetHostForChildProcess(int child_process_id) {
+PepperRendererConnection::PepperRendererConnection(int render_process_id)
+ : render_process_id_(render_process_id) {
+ // Only give the renderer permission for stable APIs.
+ in_process_host_.reset(new BrowserPpapiHostImpl(this,
+ ppapi::PpapiPermissions(),
+ "",
+ base::FilePath(),
+ base::FilePath(),
+ false));
+}
+
+PepperRendererConnection::~PepperRendererConnection() {
+}
+
+BrowserPpapiHostImpl* PepperRendererConnection::GetHostForChildProcess(
+ int child_process_id) const {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
// Find the plugin which this message refers to. Check NaCl plugins first.
@@ -40,24 +54,31 @@ BrowserPpapiHostImpl* GetHostForChildProcess(int child_process_id) {
}
}
}
- return host;
-}
-} // namespace
-PepperRendererConnection::PepperRendererConnection() {
-}
+ // If the message is being sent from an in-process plugin, we own the
+ // BrowserPpapiHost.
+ if (!host && child_process_id == 0) {
+ host = in_process_host_.get();
+ }
-PepperRendererConnection::~PepperRendererConnection() {
+ return host;
}
bool PepperRendererConnection::OnMessageReceived(const IPC::Message& msg,
bool* message_was_ok) {
+ if (in_process_host_->GetPpapiHost()->OnMessageReceived(msg))
+ return true;
+
bool handled = true;
IPC_BEGIN_MESSAGE_MAP_EX(PepperRendererConnection, msg, *message_was_ok)
IPC_MESSAGE_HANDLER(PpapiHostMsg_CreateResourceHostFromHost,
OnMsgCreateResourceHostFromHost)
IPC_MESSAGE_HANDLER(PpapiHostMsg_FileRef_GetInfoForRenderer,
OnMsgFileRefGetInfoForRenderer)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_DidCreateInProcessInstance,
+ OnMsgDidCreateInProcessInstance)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_DidDeleteInProcessInstance,
+ OnMsgDidDeleteInProcessInstance)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP_EX()
@@ -71,6 +92,7 @@ void PepperRendererConnection::OnMsgCreateResourceHostFromHost(
PP_Instance instance,
const IPC::Message& nested_msg) {
BrowserPpapiHostImpl* host = GetHostForChildProcess(child_process_id);
+
int pending_resource_host_id;
if (!host) {
DLOG(ERROR) << "Invalid plugin process ID.";
@@ -107,29 +129,48 @@ void PepperRendererConnection::OnMsgCreateResourceHostFromHost(
void PepperRendererConnection::OnMsgFileRefGetInfoForRenderer(
int routing_id,
int child_process_id,
- const ppapi::proxy::ResourceMessageCallParams& params) {
- PP_FileSystemType fs_type = PP_FILESYSTEMTYPE_INVALID;
- std::string file_system_url_spec;
- base::FilePath external_path;
+ int32_t sequence,
+ const std::vector<PP_Resource>& resources) {
+ std::vector<PP_Resource> out_resources;
+ std::vector<PP_FileSystemType> fs_types;
+ std::vector<std::string> file_system_url_specs;
+ std::vector<base::FilePath> external_paths;
+
BrowserPpapiHostImpl* host = GetHostForChildProcess(child_process_id);
if (host) {
- ppapi::host::ResourceHost* resource_host =
- host->GetPpapiHost()->GetResourceHost(params.pp_resource());
- if (resource_host) {
- PepperFileRefHost* file_ref_host = resource_host->AsPepperFileRefHost();
- if (file_ref_host) {
- fs_type = file_ref_host->GetFileSystemType();
- file_system_url_spec = file_ref_host->GetFileSystemURLSpec();
- external_path = file_ref_host->GetExternalPath();
+ for (size_t i = 0; i < resources.size(); ++i) {
+ ppapi::host::ResourceHost* resource_host =
+ host->GetPpapiHost()->GetResourceHost(resources[i]);
+ if (resource_host && resource_host->IsFileRefHost()) {
+ PepperFileRefHost* file_ref_host =
+ static_cast<PepperFileRefHost*>(resource_host);
+ out_resources.push_back(resources[i]);
+ fs_types.push_back(file_ref_host->GetFileSystemType());
+ file_system_url_specs.push_back(file_ref_host->GetFileSystemURLSpec());
+ external_paths.push_back(file_ref_host->GetExternalPath());
}
}
}
Send(new PpapiHostMsg_FileRef_GetInfoForRendererReply(
routing_id,
- params.sequence(),
- fs_type,
- file_system_url_spec,
- external_path));
+ sequence,
+ out_resources,
+ fs_types,
+ file_system_url_specs,
+ external_paths));
+}
+
+void PepperRendererConnection::OnMsgDidCreateInProcessInstance(
+ PP_Instance instance,
+ const PepperRendererInstanceData& instance_data) {
+ PepperRendererInstanceData data = instance_data;
+ data.render_process_id = render_process_id_;
+ in_process_host_->AddInstance(instance, data);
+}
+
+void PepperRendererConnection::OnMsgDidDeleteInProcessInstance(
+ PP_Instance instance) {
+ in_process_host_->DeleteInstance(instance);
}
} // namespace content
diff --git a/content/browser/renderer_host/pepper/pepper_renderer_connection.h b/content/browser/renderer_host/pepper/pepper_renderer_connection.h
index 5b2054ee83..43923465d0 100644
--- a/content/browser/renderer_host/pepper/pepper_renderer_connection.h
+++ b/content/browser/renderer_host/pepper/pepper_renderer_connection.h
@@ -7,10 +7,13 @@
#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/memory/scoped_ptr.h"
#include "content/public/browser/browser_message_filter.h"
#include "ppapi/c/pp_instance.h"
#include "ppapi/c/pp_resource.h"
+class GURL;
+
namespace ppapi {
namespace proxy {
class ResourceMessageCallParams;
@@ -19,13 +22,16 @@ class ResourceMessageCallParams;
namespace content {
+class BrowserPpapiHostImpl;
+struct PepperRendererInstanceData;
+
// This class represents a connection from the browser to the renderer for
// sending/receiving pepper ResourceHost related messages. When the browser
// and renderer communicate about ResourceHosts, they should pass the plugin
// process ID to identify which plugin they are talking about.
class PepperRendererConnection : public BrowserMessageFilter {
public:
- PepperRendererConnection();
+ explicit PepperRendererConnection(int render_process_id);
// BrowserMessageFilter overrides.
virtual bool OnMessageReceived(const IPC::Message& msg,
@@ -34,6 +40,11 @@ class PepperRendererConnection : public BrowserMessageFilter {
private:
virtual ~PepperRendererConnection();
+ // Returns the host for the child process for the given |child_process_id|.
+ // If |child_process_id| is 0, returns the host owned by this
+ // PepperRendererConnection, which serves as the host for in-process plugins.
+ BrowserPpapiHostImpl* GetHostForChildProcess(int child_process_id) const;
+
void OnMsgCreateResourceHostFromHost(
int routing_id,
int child_process_id,
@@ -44,7 +55,21 @@ class PepperRendererConnection : public BrowserMessageFilter {
void OnMsgFileRefGetInfoForRenderer(
int routing_id,
int child_process_id,
- const ppapi::proxy::ResourceMessageCallParams& params);
+ int32_t sequence_num,
+ const std::vector<PP_Resource>& resources);
+
+ void OnMsgDidCreateInProcessInstance(
+ PP_Instance instance,
+ const PepperRendererInstanceData& instance_data);
+ void OnMsgDidDeleteInProcessInstance(PP_Instance instance);
+
+ int render_process_id_;
+
+ // We have a single BrowserPpapiHost per-renderer for all in-process plugins
+ // running. This is just a work-around allowing new style resources to work
+ // with the browser when running in-process but it means that plugin-specific
+ // information (like the plugin name) won't be available.
+ scoped_ptr<BrowserPpapiHostImpl> in_process_host_;
DISALLOW_COPY_AND_ASSIGN(PepperRendererConnection);
};
diff --git a/content/browser/renderer_host/pepper/pepper_security_helper.cc b/content/browser/renderer_host/pepper/pepper_security_helper.cc
new file mode 100644
index 0000000000..5402823f01
--- /dev/null
+++ b/content/browser/renderer_host/pepper/pepper_security_helper.cc
@@ -0,0 +1,54 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/renderer_host/pepper/pepper_security_helper.h"
+
+#include "base/logging.h"
+#include "content/browser/child_process_security_policy_impl.h"
+#include "ppapi/c/ppb_file_io.h"
+
+namespace content {
+
+bool CanOpenWithPepperFlags(int pp_open_flags, int child_id,
+ const base::FilePath& file) {
+ ChildProcessSecurityPolicyImpl* policy =
+ ChildProcessSecurityPolicyImpl::GetInstance();
+
+ bool pp_read = !!(pp_open_flags & PP_FILEOPENFLAG_READ);
+ bool pp_write = !!(pp_open_flags & PP_FILEOPENFLAG_WRITE);
+ bool pp_create = !!(pp_open_flags & PP_FILEOPENFLAG_CREATE);
+ bool pp_truncate = !!(pp_open_flags & PP_FILEOPENFLAG_TRUNCATE);
+ bool pp_exclusive = !!(pp_open_flags & PP_FILEOPENFLAG_EXCLUSIVE);
+ bool pp_append = !!(pp_open_flags & PP_FILEOPENFLAG_APPEND);
+
+ if (pp_read && !policy->CanReadFile(child_id, file))
+ return false;
+
+ if (pp_write && !policy->CanWriteFile(child_id, file))
+ return false;
+
+ if (pp_append) {
+ // Given ChildSecurityPolicyImpl's current definition of permissions,
+ // APPEND is never supported.
+ return false;
+ }
+
+ if (pp_truncate && !pp_write)
+ return false;
+
+ if (pp_create) {
+ if (pp_exclusive) {
+ return policy->CanCreateFile(child_id, file);
+ } else {
+ // Asks for too much, but this is the only grant that allows overwrite.
+ return policy->CanCreateWriteFile(child_id, file);
+ }
+ } else if (pp_truncate) {
+ return policy->CanCreateWriteFile(child_id, file);
+ }
+
+ return true;
+}
+
+} // namespace content
diff --git a/content/browser/renderer_host/pepper/pepper_security_helper.h b/content/browser/renderer_host/pepper/pepper_security_helper.h
new file mode 100644
index 0000000000..4a3cea5874
--- /dev/null
+++ b/content/browser/renderer_host/pepper/pepper_security_helper.h
@@ -0,0 +1,21 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_SECURITY_HELPER_H_
+#define CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_SECURITY_HELPER_H_
+
+#include "base/files/file_path.h"
+#include "content/common/content_export.h"
+
+namespace content {
+
+// Helper method that returns whether or not the child process is allowed to
+// open the specified |file| with the specified |pp_open_flags|.
+CONTENT_EXPORT bool CanOpenWithPepperFlags(int pp_open_flags,
+ int child_id,
+ const base::FilePath& file);
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_SECURITY_HELPER_H_
diff --git a/content/browser/renderer_host/render_message_filter.cc b/content/browser/renderer_host/render_message_filter.cc
index 3f2f100b84..daab4ed75e 100644
--- a/content/browser/renderer_host/render_message_filter.cc
+++ b/content/browser/renderer_host/render_message_filter.cc
@@ -25,6 +25,7 @@
#include "content/browser/plugin_process_host.h"
#include "content/browser/plugin_service_impl.h"
#include "content/browser/ppapi_plugin_process_host.h"
+#include "content/browser/renderer_host/pepper/pepper_security_helper.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/renderer_host/render_view_host_delegate.h"
#include "content/browser/renderer_host/render_widget_helper.h"
@@ -61,6 +62,7 @@
#include "net/http/http_cache.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
+#include "ppapi/shared_impl/file_type_conversion.h"
#include "third_party/WebKit/public/web/WebNotificationPresenter.h"
#include "ui/gfx/color_profile.h"
#include "webkit/plugins/plugin_constants.h"
@@ -393,6 +395,7 @@ bool RenderMessageFilter::OnMessageReceived(const IPC::Message& message,
OnDidDeleteOutOfProcessPepperInstance)
IPC_MESSAGE_HANDLER(ViewHostMsg_OpenChannelToPpapiBroker,
OnOpenChannelToPpapiBroker)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_AsyncOpenPepperFile, OnAsyncOpenPepperFile)
#endif
IPC_MESSAGE_HANDLER_GENERIC(ViewHostMsg_UpdateRect,
render_widget_helper_->DidReceiveBackingStoreMsg(message))
@@ -408,7 +411,6 @@ bool RenderMessageFilter::OnMessageReceived(const IPC::Message& message,
IPC_MESSAGE_HANDLER(ViewHostMsg_DidGenerateCacheableMetadata,
OnCacheableMetadataAvailable)
IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_Keygen, OnKeygen)
- IPC_MESSAGE_HANDLER(ViewHostMsg_AsyncOpenFile, OnAsyncOpenFile)
IPC_MESSAGE_HANDLER(ViewHostMsg_GetCPUUsage, OnGetCPUUsage)
IPC_MESSAGE_HANDLER(ViewHostMsg_GetAudioHardwareConfig,
OnGetAudioHardwareConfig)
@@ -987,15 +989,19 @@ void RenderMessageFilter::OnKeygenOnWorkerThread(
Send(reply_msg);
}
-void RenderMessageFilter::OnAsyncOpenFile(const IPC::Message& msg,
- const base::FilePath& path,
- int flags,
- int message_id) {
+void RenderMessageFilter::OnAsyncOpenPepperFile(const IPC::Message& msg,
+ const base::FilePath& path,
+ int pp_open_flags,
+ int message_id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- if (!ChildProcessSecurityPolicyImpl::GetInstance()->HasPermissionsForFile(
- render_process_id_, path, flags)) {
- DLOG(ERROR) << "Bad flags in ViewMsgHost_AsyncOpenFile message: " << flags;
+ int platform_file_flags = 0;
+ if (!CanOpenWithPepperFlags(pp_open_flags, render_process_id_, path) ||
+ !ppapi::PepperFileOpenFlagsToPlatformFileFlags(
+ pp_open_flags, &platform_file_flags)) {
+ DLOG(ERROR) <<
+ "Bad pp_open_flags in ViewMsgHost_AsyncOpenPepperFile message: " <<
+ pp_open_flags;
RecordAction(UserMetricsAction("BadMessageTerminate_AOF"));
BadMessageReceived();
return;
@@ -1003,25 +1009,29 @@ void RenderMessageFilter::OnAsyncOpenFile(const IPC::Message& msg,
BrowserThread::PostTask(
BrowserThread::FILE, FROM_HERE, base::Bind(
- &RenderMessageFilter::AsyncOpenFileOnFileThread, this,
- path, flags, message_id, msg.routing_id()));
+ &RenderMessageFilter::AsyncOpenPepperFileOnFileThread, this,
+ path, platform_file_flags, message_id, msg.routing_id()));
}
-void RenderMessageFilter::AsyncOpenFileOnFileThread(const base::FilePath& path,
- int flags,
- int message_id,
- int routing_id) {
+void RenderMessageFilter::AsyncOpenPepperFileOnFileThread(
+ const base::FilePath& path,
+ int platform_file_flags,
+ int message_id,
+ int routing_id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
base::PlatformFileError error_code = base::PLATFORM_FILE_OK;
base::PlatformFile file = base::CreatePlatformFile(
- path, flags, NULL, &error_code);
+ path, platform_file_flags, NULL, &error_code);
IPC::PlatformFileForTransit file_for_transit =
file != base::kInvalidPlatformFileValue ?
IPC::GetFileHandleForProcess(file, PeerHandle(), true) :
IPC::InvalidPlatformFileForTransit();
- IPC::Message* reply = new ViewMsg_AsyncOpenFile_ACK(
- routing_id, error_code, file_for_transit, message_id);
+ IPC::Message* reply = new ViewMsg_AsyncOpenPepperFile_ACK(
+ routing_id,
+ error_code,
+ file_for_transit,
+ message_id);
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(base::IgnoreResult(&RenderMessageFilter::Send), this, reply));
diff --git a/content/browser/renderer_host/render_message_filter.h b/content/browser/renderer_host/render_message_filter.h
index 00cdc6a0d8..e6f19957d1 100644
--- a/content/browser/renderer_host/render_message_filter.h
+++ b/content/browser/renderer_host/render_message_filter.h
@@ -224,14 +224,14 @@ class RenderMessageFilter : public BrowserMessageFilter {
const std::string& challenge_string,
const GURL& url,
IPC::Message* reply_msg);
- void OnAsyncOpenFile(const IPC::Message& msg,
- const base::FilePath& path,
- int flags,
- int message_id);
- void AsyncOpenFileOnFileThread(const base::FilePath& path,
- int flags,
- int message_id,
- int routing_id);
+ void OnAsyncOpenPepperFile(const IPC::Message& msg,
+ const base::FilePath& path,
+ int pp_open_flags,
+ int message_id);
+ void AsyncOpenPepperFileOnFileThread(const base::FilePath& path,
+ int platform_file_flags,
+ int message_id,
+ int routing_id);
void OnMediaLogEvents(const std::vector<media::MediaLogEvent>&);
// Check the policy for getting cookies. Gets the cookies if allowed.
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
index a9ea4d9f6b..22b27e987d 100644
--- a/content/browser/renderer_host/render_process_host_impl.cc
+++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -54,7 +54,6 @@
#include "content/browser/gpu/gpu_process_host.h"
#include "content/browser/gpu/shader_disk_cache.h"
#include "content/browser/histogram_message_filter.h"
-#include "content/browser/hyphenator/hyphenator_message_filter.h"
#include "content/browser/indexed_db/indexed_db_context_impl.h"
#include "content/browser/indexed_db/indexed_db_dispatcher_host.h"
#include "content/browser/loader/resource_message_filter.h"
@@ -75,6 +74,7 @@
#include "content/browser/renderer_host/media/audio_renderer_host.h"
#include "content/browser/renderer_host/media/device_request_message_filter.h"
#include "content/browser/renderer_host/media/media_stream_dispatcher_host.h"
+#include "content/browser/renderer_host/media/midi_dispatcher_host.h"
#include "content/browser/renderer_host/media/midi_host.h"
#include "content/browser/renderer_host/media/peer_connection_tracker_host.h"
#include "content/browser/renderer_host/media/video_capture_host.h"
@@ -410,7 +410,8 @@ RenderProcessHostImpl::RenderProcessHostImpl(
ignore_input_events_(false),
supports_browser_plugin_(supports_browser_plugin),
is_guest_(is_guest),
- gpu_observer_registered_(false) {
+ gpu_observer_registered_(false),
+ power_monitor_broadcaster_(this) {
widget_helper_ = new RenderWidgetHelper();
ChildProcessSecurityPolicyImpl::GetInstance()->Add(GetID());
@@ -622,6 +623,7 @@ void RenderProcessHostImpl::CreateMessageFilters() {
media_internals, media_stream_manager));
channel_->AddFilter(
new MIDIHost(BrowserMainLoop::GetInstance()->midi_manager()));
+ channel_->AddFilter(new MIDIDispatcherHost(GetID(), browser_context));
channel_->AddFilter(new VideoCaptureHost(media_stream_manager));
channel_->AddFilter(new AppCacheDispatcherHost(
storage_partition_impl_->GetAppCacheService(),
@@ -658,7 +660,7 @@ void RenderProcessHostImpl::CreateMessageFilters() {
#if defined(ENABLE_PLUGINS)
// TODO(raymes): PepperMessageFilter should be removed from here.
channel_->AddFilter(new PepperMessageFilter(GetID(), browser_context));
- channel_->AddFilter(new PepperRendererConnection);
+ channel_->AddFilter(new PepperRendererConnection(GetID()));
#endif
#if defined(ENABLE_INPUT_SPEECH)
channel_->AddFilter(new InputTagSpeechDispatcherHost(
@@ -719,7 +721,6 @@ void RenderProcessHostImpl::CreateMessageFilters() {
channel_->AddFilter(new DeviceMotionBrowserMessageFilter());
channel_->AddFilter(new ProfilerMessageFilter(PROCESS_TYPE_RENDERER));
channel_->AddFilter(new HistogramMessageFilter());
- channel_->AddFilter(new HyphenatorMessageFilter(this));
#if defined(USE_TCMALLOC) && (defined(OS_LINUX) || defined(OS_ANDROID))
if (CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableMemoryBenchmarking))
@@ -884,6 +885,7 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
switches::kDisableGLMultisampling,
switches::kDisableGpuVsync,
switches::kDisableGpu,
+ switches::kDisableGpuCompositing,
switches::kDisableHistogramCustomizer,
switches::kDisableLocalStorage,
switches::kDisableLogging,
@@ -900,7 +902,7 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
#endif
switches::kDisableWebAudio,
#if defined(ENABLE_WEBRTC)
- switches::kEnableDeviceEnumeration,
+ switches::kDisableDeviceEnumeration,
switches::kEnableSCTPDataChannels,
#endif
switches::kEnableWebAnimationsCSS,
@@ -953,7 +955,7 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
// Allow this to be set when invoking the browser and relayed along.
switches::kEnableSandboxLogging,
#endif
- switches::kEnableSoftwareCompositingGLAdapter,
+ switches::kEnableSoftwareCompositing,
switches::kEnableStatsTable,
switches::kEnableThreadedCompositing,
switches::kEnableCompositingForFixedPosition,
@@ -1026,6 +1028,9 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
switches::kEnableWebGLDraftExtensions,
switches::kTraceToConsole,
switches::kEnableDeviceMotion,
+#if defined(OS_ANDROID)
+ switches::kDisableDeviceMotion,
+#endif
// Please keep these in alphabetical order. Compositor switches here should
// also be added to chrome/browser/chromeos/login/chrome_restart_request.cc.
cc::switches::kBackgroundColorInsteadOfCheckerboard,
diff --git a/content/browser/renderer_host/render_process_host_impl.h b/content/browser/renderer_host/render_process_host_impl.h
index 65d85a00b3..72ec846303 100644
--- a/content/browser/renderer_host/render_process_host_impl.h
+++ b/content/browser/renderer_host/render_process_host_impl.h
@@ -13,6 +13,7 @@
#include "base/process/process.h"
#include "base/timer/timer.h"
#include "content/browser/child_process_launcher.h"
+#include "content/browser/power_monitor_message_broadcaster.h"
#include "content/common/content_export.h"
#include "content/public/browser/global_request_id.h"
#include "content/public/browser/gpu_data_manager_observer.h"
@@ -320,6 +321,9 @@ class CONTENT_EXPORT RenderProcessHostImpl
// than once.
bool gpu_observer_registered_;
+ // Forwards power state messages to the renderer process.
+ PowerMonitorMessageBroadcaster power_monitor_broadcaster_;
+
DISALLOW_COPY_AND_ASSIGN(RenderProcessHostImpl);
};
diff --git a/content/browser/renderer_host/render_sandbox_host_linux.cc b/content/browser/renderer_host/render_sandbox_host_linux.cc
index d2b45923ce..87d31dca88 100644
--- a/content/browser/renderer_host/render_sandbox_host_linux.cc
+++ b/content/browser/renderer_host/render_sandbox_host_linux.cc
@@ -40,6 +40,7 @@
using WebKit::WebCString;
using WebKit::WebFontInfo;
using WebKit::WebUChar;
+using WebKit::WebUChar32;
namespace content {
@@ -142,8 +143,8 @@ class SandboxIPCProcess {
HandleFontMatchRequest(fd, pickle, iter, fds);
} else if (kind == FontConfigIPC::METHOD_OPEN) {
HandleFontOpenRequest(fd, pickle, iter, fds);
- } else if (kind == LinuxSandbox::METHOD_GET_FONT_FAMILY_FOR_CHARS) {
- HandleGetFontFamilyForChars(fd, pickle, iter, fds);
+ } else if (kind == LinuxSandbox::METHOD_GET_FONT_FAMILY_FOR_CHAR) {
+ HandleGetFontFamilyForChar(fd, pickle, iter, fds);
} else if (kind == LinuxSandbox::METHOD_LOCALTIME) {
HandleLocaltime(fd, pickle, iter, fds);
} else if (kind == LinuxSandbox::METHOD_GET_CHILD_WITH_INODE) {
@@ -233,46 +234,23 @@ class SandboxIPCProcess {
}
}
- void HandleGetFontFamilyForChars(int fd, const Pickle& pickle,
- PickleIterator iter,
- std::vector<int>& fds) {
+ void HandleGetFontFamilyForChar(int fd, const Pickle& pickle,
+ PickleIterator iter,
+ std::vector<int>& fds) {
// The other side of this call is
// chrome/renderer/renderer_sandbox_support_linux.cc
- int num_chars;
- if (!pickle.ReadInt(&iter, &num_chars))
- return;
-
- // We don't want a corrupt renderer asking too much of us, it might
- // overflow later in the code.
- static const int kMaxChars = 4096;
- if (num_chars < 1 || num_chars > kMaxChars) {
- LOG(WARNING) << "HandleGetFontFamilyForChars: too many chars: "
- << num_chars;
- return;
- }
-
EnsureWebKitInitialized();
- scoped_ptr<WebUChar[]> chars(new WebUChar[num_chars]);
-
- for (int i = 0; i < num_chars; ++i) {
- uint32_t c;
- if (!pickle.ReadUInt32(&iter, &c)) {
- return;
- }
-
- chars[i] = c;
- }
+ WebUChar32 c;
+ if (!pickle.ReadInt(&iter, &c))
+ return;
std::string preferred_locale;
if (!pickle.ReadString(&iter, &preferred_locale))
return;
WebKit::WebFontFamily family;
- WebFontInfo::familyForChars(chars.get(),
- num_chars,
- preferred_locale.c_str(),
- &family);
+ WebFontInfo::familyForChar(c, preferred_locale.c_str(), &family);
Pickle reply;
if (family.name.data()) {
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
index c08d897f86..edd21fe598 100644
--- a/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -2107,7 +2107,7 @@ void RenderWidgetHostImpl::OnGestureEventAck(
overscroll_controller_->ReceivedEventACK(event, processed);
if (view_)
- view_->GestureEventAck(event.type);
+ view_->GestureEventAck(event.type, ack_result);
}
void RenderWidgetHostImpl::OnTouchEventAck(
@@ -2439,12 +2439,14 @@ void RenderWidgetHostImpl::FrameSwapped(const ui::LatencyInfo& latency_info) {
// results in final frame swap.
base::TimeDelta delta =
latency_info.swap_timestamp - original_component.event_time;
- UMA_HISTOGRAM_CUSTOM_COUNTS(
- "Event.Latency.TouchToScrollUpdateSwap",
- delta.InMicroseconds(),
- 0,
- 1000000,
- 100);
+ for (size_t i = 0; i < original_component.event_count; i++) {
+ UMA_HISTOGRAM_CUSTOM_COUNTS(
+ "Event.Latency.TouchToScrollUpdateSwap",
+ delta.InMicroseconds(),
+ 0,
+ 1000000,
+ 100);
+ }
rendering_stats_.scroll_update_count += original_component.event_count;
rendering_stats_.total_scroll_update_latency +=
original_component.event_count *
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc
index 806f35ff2f..3282ca90a8 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.cc
+++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -46,6 +46,8 @@ namespace content {
namespace {
+const int kUndefinedOutputSurfaceId = -1;
+
void InsertSyncPointAndAckForGpu(
int gpu_host_id, int route_id, const std::string& return_mailbox) {
uint32 sync_point =
@@ -87,6 +89,7 @@ RenderWidgetHostViewAndroid::RenderWidgetHostViewAndroid(
ime_adapter_android_(this),
cached_background_color_(SK_ColorWHITE),
texture_id_in_layer_(0),
+ current_mailbox_output_surface_id_(kUndefinedOutputSurfaceId),
weak_ptr_factory_(this),
overscroll_effect_enabled_(true) {
if (CompositorImpl::UsesDirectGL()) {
@@ -632,6 +635,11 @@ void RenderWidgetHostViewAndroid::OnSwapCompositorFrame(
if (!frame->gl_frame_data || frame->gl_frame_data->mailbox.IsZero())
return;
+ if (output_surface_id != current_mailbox_output_surface_id_) {
+ current_mailbox_ = gpu::Mailbox();
+ current_mailbox_output_surface_id_ = kUndefinedOutputSurfaceId;
+ }
+
base::Closure callback = base::Bind(&InsertSyncPointAndAckForCompositor,
host_->GetProcess()->GetID(),
output_surface_id,
@@ -647,7 +655,7 @@ void RenderWidgetHostViewAndroid::OnSwapCompositorFrame(
if (layer_->layer_tree_host())
layer_->layer_tree_host()->SetLatencyInfo(frame->metadata.latency_info);
- BuffersSwapped(frame->gl_frame_data->mailbox, callback);
+ BuffersSwapped(frame->gl_frame_data->mailbox, output_surface_id, callback);
}
void RenderWidgetHostViewAndroid::SynchronousFrameMetadata(
@@ -702,11 +710,12 @@ void RenderWidgetHostViewAndroid::AcceleratedSurfaceBuffersSwapped(
texture_size_in_layer_ = params.size;
content_size_in_layer_ = params.size;
- BuffersSwapped(mailbox, callback);
+ BuffersSwapped(mailbox, kUndefinedOutputSurfaceId, callback);
}
void RenderWidgetHostViewAndroid::BuffersSwapped(
const gpu::Mailbox& mailbox,
+ uint32_t output_surface_id,
const base::Closure& ack_callback) {
ImageTransportFactoryAndroid* factory =
ImageTransportFactoryAndroid::GetInstance();
@@ -727,6 +736,7 @@ void RenderWidgetHostViewAndroid::BuffersSwapped(
ResetClipping();
current_mailbox_ = mailbox;
+ current_mailbox_output_surface_id_ = output_surface_id;
if (host_->is_hidden())
ack_callback.Run();
@@ -814,6 +824,7 @@ void RenderWidgetHostViewAndroid::AcceleratedSurfaceRelease() {
texture_id_in_layer_);
texture_id_in_layer_ = 0;
current_mailbox_ = gpu::Mailbox();
+ current_mailbox_output_surface_id_ = kUndefinedOutputSurfaceId;
}
}
@@ -864,6 +875,15 @@ void RenderWidgetHostViewAndroid::UnhandledWheelEvent(
// intentionally empty, like RenderWidgetHostViewViews
}
+void RenderWidgetHostViewAndroid::GestureEventAck(
+ int gesture_event_type,
+ InputEventAckState ack_result) {
+ if (gesture_event_type == WebKit::WebInputEvent::GestureFlingStart &&
+ ack_result == INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS) {
+ content_view_core_->UnhandledFlingStartEvent();
+ }
+}
+
InputEventAckState RenderWidgetHostViewAndroid::FilterInputEvent(
const WebKit::WebInputEvent& input_event) {
if (host_) {
@@ -878,6 +898,12 @@ InputEventAckState RenderWidgetHostViewAndroid::FilterInputEvent(
void RenderWidgetHostViewAndroid::OnAccessibilityNotifications(
const std::vector<AccessibilityHostMsg_NotificationParams>& params) {
+ if (!host_ ||
+ host_->accessibility_mode() != AccessibilityModeComplete ||
+ !content_view_core_) {
+ return;
+ }
+
if (!GetBrowserAccessibilityManager()) {
SetBrowserAccessibilityManager(
new BrowserAccessibilityManagerAndroid(
@@ -1111,7 +1137,6 @@ void RenderWidgetHostViewAndroid::OnLostResources() {
if (texture_layer_)
texture_layer_->SetIsDrawable(false);
texture_id_in_layer_ = 0;
- current_mailbox_ = gpu::Mailbox();
RunAckCallbacks();
}
diff --git a/content/browser/renderer_host/render_widget_host_view_android.h b/content/browser/renderer_host/render_widget_host_view_android.h
index 630ead9b0c..d9b0d97248 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.h
+++ b/content/browser/renderer_host/render_widget_host_view_android.h
@@ -149,6 +149,8 @@ class RenderWidgetHostViewAndroid
const WebKit::WebMouseWheelEvent& event) OVERRIDE;
virtual InputEventAckState FilterInputEvent(
const WebKit::WebInputEvent& input_event) OVERRIDE;
+ virtual void GestureEventAck(int gesture_event_type,
+ InputEventAckState ack_result) OVERRIDE;
virtual void OnAccessibilityNotifications(
const std::vector<AccessibilityHostMsg_NotificationParams>&
params) OVERRIDE;
@@ -232,6 +234,7 @@ class RenderWidgetHostViewAndroid
private:
void BuffersSwapped(const gpu::Mailbox& mailbox,
+ uint32_t output_surface_id,
const base::Closure& ack_callback);
void RunAckCallbacks();
@@ -297,6 +300,7 @@ class RenderWidgetHostViewAndroid
// The mailbox of the previously received frame.
gpu::Mailbox current_mailbox_;
+ uint32_t current_mailbox_output_surface_id_;
base::WeakPtrFactory<RenderWidgetHostViewAndroid> weak_ptr_factory_;
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
index f95a70e40e..dc239349e4 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -979,8 +979,7 @@ bool RenderWidgetHostViewAura::HasFocus() const {
}
bool RenderWidgetHostViewAura::IsSurfaceAvailableForCopy() const {
- return window_->layer()->has_external_content() ||
- !!host_->GetBackingStore(false);
+ return CanCopyToBitmap() || !!host_->GetBackingStore(false);
}
void RenderWidgetHostViewAura::Show() {
@@ -1198,7 +1197,7 @@ void RenderWidgetHostViewAura::CopyFromCompositingSurface(
const gfx::Rect& src_subrect,
const gfx::Size& dst_size,
const base::Callback<void(bool, const SkBitmap&)>& callback) {
- if (!window_->layer()->has_external_content()) {
+ if (!CanCopyToBitmap()) {
callback.Run(false, SkBitmap());
return;
}
@@ -1219,7 +1218,7 @@ void RenderWidgetHostViewAura::CopyFromCompositingSurfaceToVideoFrame(
const gfx::Rect& src_subrect,
const scoped_refptr<media::VideoFrame>& target,
const base::Callback<void(bool)>& callback) {
- if (!window_->layer()->has_external_content()) {
+ if (!CanCopyToVideoFrame()) {
callback.Run(false);
return;
}
@@ -1237,9 +1236,15 @@ void RenderWidgetHostViewAura::CopyFromCompositingSurfaceToVideoFrame(
window_->layer()->RequestCopyOfOutput(request.Pass());
}
+bool RenderWidgetHostViewAura::CanCopyToBitmap() const {
+ return GetCompositor() && window_->layer()->has_external_content();
+}
+
bool RenderWidgetHostViewAura::CanCopyToVideoFrame() const {
- // TODO(skaslev): Implement this path for s/w compositing.
- return window_->layer()->has_external_content() &&
+ // TODO(skaslev): Implement this path for s/w compositing by handling software
+ // CopyOutputResult in CopyFromCompositingSurfaceHasResultForVideo().
+ return GetCompositor() &&
+ window_->layer()->has_external_content() &&
host_->is_accelerated_compositing_active();
}
@@ -1363,8 +1368,18 @@ void RenderWidgetHostViewAura::SwapBuffersCompleted(
const BufferPresentedCallback& ack_callback,
const scoped_refptr<ui::Texture>& texture_to_return) {
ui::Compositor* compositor = GetCompositor();
+ if (!compositor) {
+ ack_callback.Run(false, texture_to_return);
+ } else {
+ AddOnCommitCallbackAndDisableLocks(
+ base::Bind(ack_callback, false, texture_to_return));
+ }
+
+ DidReceiveFrameFromRenderer();
+}
- if (frame_subscriber() && current_surface_.get() != NULL) {
+void RenderWidgetHostViewAura::DidReceiveFrameFromRenderer() {
+ if (frame_subscriber() && CanCopyToVideoFrame()) {
const base::Time present_time = base::Time::Now();
scoped_refptr<media::VideoFrame> frame;
RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback callback;
@@ -1377,13 +1392,6 @@ void RenderWidgetHostViewAura::SwapBuffersCompleted(
base::Bind(callback, present_time));
}
}
-
- if (!compositor) {
- ack_callback.Run(false, texture_to_return);
- } else {
- AddOnCommitCallbackAndDisableLocks(
- base::Bind(ack_callback, false, texture_to_return));
- }
}
#if defined(OS_WIN)
@@ -1468,6 +1476,7 @@ void RenderWidgetHostViewAura::SwapDelegatedFrame(
AsWeakPtr(),
output_surface_id));
}
+ DidReceiveFrameFromRenderer();
}
void RenderWidgetHostViewAura::SendDelegatedFrameAck(uint32 output_surface_id) {
@@ -1537,6 +1546,7 @@ void RenderWidgetHostViewAura::SwapSoftwareFrame(
compositor->SetLatencyInfo(latency_info);
if (paint_observer_)
paint_observer_->OnUpdateCompositorContent();
+ DidReceiveFrameFromRenderer();
}
void RenderWidgetHostViewAura::SendSoftwareFrameAck(
@@ -1945,7 +1955,8 @@ gfx::Rect RenderWidgetHostViewAura::GetBoundsInRootWindow() {
return window_->GetToplevelWindow()->GetBoundsInScreen();
}
-void RenderWidgetHostViewAura::GestureEventAck(int gesture_event_type) {
+void RenderWidgetHostViewAura::GestureEventAck(int gesture_event_type,
+ InputEventAckState ack_result) {
if (touch_editing_client_)
touch_editing_client_->GestureEventAck(gesture_event_type);
}
@@ -2004,7 +2015,8 @@ gfx::GLSurfaceHandle RenderWidgetHostViewAura::GetCompositingSurface() {
if (shared_surface_handle_.is_null()) {
ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
shared_surface_handle_ = factory->CreateSharedSurfaceHandle();
- factory->AddObserver(this);
+ if (!shared_surface_handle_.is_null())
+ factory->AddObserver(this);
}
return shared_surface_handle_;
}
@@ -2480,6 +2492,32 @@ 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(
@@ -3151,7 +3189,7 @@ void RenderWidgetHostViewAura::RemovingFromRootWindow() {
compositor->RemoveObserver(this);
}
-ui::Compositor* RenderWidgetHostViewAura::GetCompositor() {
+ui::Compositor* RenderWidgetHostViewAura::GetCompositor() const {
aura::RootWindow* root_window = window_->GetRootWindow();
return root_window ? root_window->compositor() : NULL;
}
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.h b/content/browser/renderer_host/render_widget_host_view_aura.h
index 428da9469d..dafe42f447 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.h
+++ b/content/browser/renderer_host/render_widget_host_view_aura.h
@@ -222,7 +222,8 @@ class RenderWidgetHostViewAura
virtual bool HasAcceleratedSurface(const gfx::Size& desired_size) OVERRIDE;
virtual void GetScreenInfo(WebKit::WebScreenInfo* results) OVERRIDE;
virtual gfx::Rect GetBoundsInRootWindow() OVERRIDE;
- virtual void GestureEventAck(int gesture_event_type) OVERRIDE;
+ virtual void GestureEventAck(int gesture_event_type,
+ InputEventAckState ack_result) OVERRIDE;
virtual void ProcessAckedTouchEvent(
const TouchEventWithLatencyInfo& touch,
InputEventAckState ack_result) OVERRIDE;
@@ -327,6 +328,8 @@ class RenderWidgetHostViewAura
virtual void OnRootWindowHostMoved(const aura::RootWindow* root,
const gfx::Point& new_origin) OVERRIDE;
+ bool CanCopyToBitmap() const;
+
#if defined(OS_WIN)
// Sets the cutout rects from constrained windows. These are rectangles that
// windowed NPAPI plugins shouldn't paint in. Overwrites any previous cutout
@@ -457,7 +460,7 @@ class RenderWidgetHostViewAura
const base::Callback<void(bool)>& callback,
scoped_ptr<cc::CopyOutputResult> result);
- ui::Compositor* GetCompositor();
+ ui::Compositor* GetCompositor() const;
// Detaches |this| from the input method object.
void DetachFromInputMethod();
@@ -508,6 +511,8 @@ class RenderWidgetHostViewAura
void SendSoftwareFrameAck(uint32 output_surface_id,
unsigned software_frame_id);
+ void DidReceiveFrameFromRenderer();
+
BrowserAccessibilityManager* GetOrCreateBrowserAccessibilityManager();
#if defined(OS_WIN)
diff --git a/content/browser/renderer_host/render_widget_host_view_base.cc b/content/browser/renderer_host/render_widget_host_view_base.cc
index 815b9446c0..b35d5b389b 100644
--- a/content/browser/renderer_host/render_widget_host_view_base.cc
+++ b/content/browser/renderer_host/render_widget_host_view_base.cc
@@ -6,6 +6,7 @@
#include "base/logging.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
+#include "content/browser/gpu/gpu_data_manager_impl.h"
#include "content/browser/renderer_host/basic_mouse_wheel_smooth_scroll_gesture.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
@@ -265,15 +266,17 @@ void RenderWidgetHostViewBase::MovePluginWindowsHelper(
flags |= SWP_HIDEWINDOW;
#if defined(USE_AURA)
- // Without this flag, Windows repaints the parent area uncovered by this
- // move. However it only looks at the plugin rectangle and ignores the
- // clipping region. In Aura, the browser chrome could be under the plugin,
- // and if Windows tries to paint it synchronously inside EndDeferWindowsPos
- // then it won't have the data and it will flash white. So instead we
- // manually redraw the plugin.
- // Why not do this for native Windows? Not sure if there are any performance
- // issues with this.
- flags |= SWP_NOREDRAW;
+ if (GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor()) {
+ // Without this flag, Windows repaints the parent area uncovered by this
+ // move. However when software compositing is used the clipping region is
+ // ignored. Since in Aura the browser chrome could be under the plugin, if
+ // if Windows tries to paint it synchronously inside EndDeferWindowsPos
+ // then it won't have the data and it will flash white. So instead we
+ // manually redraw the plugin.
+ // Why not do this for native Windows? Not sure if there are any
+ // performance issues with this.
+ flags |= SWP_NOREDRAW;
+ }
#endif
if (move.rects_valid) {
@@ -311,12 +314,14 @@ void RenderWidgetHostViewBase::MovePluginWindowsHelper(
::EndDeferWindowPos(defer_window_pos_info);
#if defined(USE_AURA)
- for (size_t i = 0; i < moves.size(); ++i) {
- const WebPluginGeometry& move = moves[i];
- RECT r;
- GetWindowRect(move.window, &r);
- gfx::Rect gr(r);
- PaintEnumChildProc(move.window, reinterpret_cast<LPARAM>(&gr));
+ if (GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor()) {
+ for (size_t i = 0; i < moves.size(); ++i) {
+ const WebPluginGeometry& move = moves[i];
+ RECT r;
+ GetWindowRect(move.window, &r);
+ gfx::Rect gr(r);
+ PaintEnumChildProc(move.window, reinterpret_cast<LPARAM>(&gr));
+ }
}
#endif
}
@@ -427,8 +432,8 @@ InputEventAckState RenderWidgetHostViewBase::FilterInputEvent(
return INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
}
-void RenderWidgetHostViewBase::GestureEventAck(int gesture_event_type) {
-}
+void RenderWidgetHostViewBase::GestureEventAck(int gesture_event_type,
+ InputEventAckState ack_result) {}
void RenderWidgetHostViewBase::SetPopupType(WebKit::WebPopupType popup_type) {
popup_type_ = popup_type;
diff --git a/content/browser/renderer_host/render_widget_host_view_base.h b/content/browser/renderer_host/render_widget_host_view_base.h
index 2efd132aba..68fcaffaea 100644
--- a/content/browser/renderer_host/render_widget_host_view_base.h
+++ b/content/browser/renderer_host/render_widget_host_view_base.h
@@ -61,7 +61,8 @@ class CONTENT_EXPORT RenderWidgetHostViewBase
const WebKit::WebMouseWheelEvent& event) OVERRIDE;
virtual InputEventAckState FilterInputEvent(
const WebKit::WebInputEvent& input_event) OVERRIDE;
- virtual void GestureEventAck(int gesture_event_type) OVERRIDE;
+ virtual void GestureEventAck(int gesture_event_type,
+ InputEventAckState ack_result) OVERRIDE;
virtual void SetPopupType(WebKit::WebPopupType popup_type) OVERRIDE;
virtual WebKit::WebPopupType GetPopupType() OVERRIDE;
virtual BrowserAccessibilityManager*
diff --git a/content/browser/renderer_host/render_widget_host_view_browsertest.cc b/content/browser/renderer_host/render_widget_host_view_browsertest.cc
index 25dd8ce884..78091320ad 100644
--- a/content/browser/renderer_host/render_widget_host_view_browsertest.cc
+++ b/content/browser/renderer_host/render_widget_host_view_browsertest.cc
@@ -855,15 +855,8 @@ class CompositingRenderWidgetHostViewTabCaptureHighDPI
DISALLOW_COPY_AND_ASSIGN(CompositingRenderWidgetHostViewTabCaptureHighDPI);
};
-// High-DPI doesn't work right with content-shell on linux-aura.
-// http://crbug.com/265028
-#if defined(USE_AURA) && defined(OS_LINUX) && !defined(OS_CHROMEOS)
-#define MAYBE_CopyFromCompositingSurface DISABLED_CopyFromCompositingSurface
-#else
-#define MAYBE_CopyFromCompositingSurface CopyFromCompositingSurface
-#endif
IN_PROC_BROWSER_TEST_F(CompositingRenderWidgetHostViewTabCaptureHighDPI,
- MAYBE_CopyFromCompositingSurface) {
+ CopyFromCompositingSurface) {
gfx::Rect copy_rect(200, 150);
gfx::Size output_size = copy_rect.size();
gfx::Size expected_bitmap_size =
@@ -877,17 +870,8 @@ IN_PROC_BROWSER_TEST_F(CompositingRenderWidgetHostViewTabCaptureHighDPI,
video_frame);
}
-// High-DPI doesn't work right with content-shell on linux-aura.
-// http://crbug.com/265028
-#if defined(USE_AURA) && defined(OS_LINUX) && !defined(OS_CHROMEOS)
-#define MAYBE_CopyFromCompositingSurfaceVideoFrame \
- DISABLED_CopyFromCompositingSurfaceVideoFrame
-#else
-#define MAYBE_CopyFromCompositingSurfaceVideoFrame \
- CopyFromCompositingSurfaceVideoFrame
-#endif
IN_PROC_BROWSER_TEST_F(CompositingRenderWidgetHostViewTabCaptureHighDPI,
- MAYBE_CopyFromCompositingSurfaceVideoFrame) {
+ CopyFromCompositingSurfaceVideoFrame) {
gfx::Size html_rect_size(200, 150);
// Grab 90x60 pixels from the center of the tab contents.
gfx::Rect copy_rect =
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.h b/content/browser/renderer_host/render_widget_host_view_mac.h
index af8106c8ce..6cbe6dc7b6 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac.h
+++ b/content/browser/renderer_host/render_widget_host_view_mac.h
@@ -463,7 +463,12 @@ class RenderWidgetHostViewMac : public RenderWidgetHostViewBase,
bool CreateCompositedIOSurface();
bool CreateCompositedIOSurfaceLayer();
- void DestroyCompositedIOSurfaceAndLayer();
+ enum DestroyContextBehavior {
+ kLeaveContextBoundToView,
+ kDestroyContext,
+ };
+ void DestroyCompositedIOSurfaceAndLayer(DestroyContextBehavior
+ destroy_context_behavior);
// Unbind the GL context (if any) that is bound to |cocoa_view_|.
void ClearBoundContextDrawable();
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm
index a7338b576c..07448884b5 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -4,6 +4,7 @@
#include "content/browser/renderer_host/render_widget_host_view_mac.h"
+#import <objc/runtime.h>
#include <QuartzCore/QuartzCore.h>
#include "base/bind.h"
@@ -137,6 +138,29 @@ static inline int ToWebKitModifiers(NSUInteger flags) {
return modifiers;
}
+// This method will return YES for OS X versions 10.7.3 and later, and NO
+// otherwise.
+// Used to prevent a crash when building with the 10.7 SDK and accessing the
+// notification below. See: http://crbug.com/260595.
+static BOOL SupportsBackingPropertiesChangedNotification() {
+ // windowDidChangeBackingProperties: method has been added to the
+ // NSWindowDelegate protocol in 10.7.3, at the same time as the
+ // NSWindowDidChangeBackingPropertiesNotification notification was added.
+ // If the protocol contains this method description, the notification should
+ // be supported as well.
+ Protocol* windowDelegateProtocol = NSProtocolFromString(@"NSWindowDelegate");
+ struct objc_method_description methodDescription =
+ protocol_getMethodDescription(
+ windowDelegateProtocol,
+ @selector(windowDidChangeBackingProperties:),
+ NO,
+ YES);
+
+ // If the protocol does not contain the method, the returned method
+ // description is {NULL, NULL}
+ return methodDescription.name != NULL || methodDescription.types != NULL;
+}
+
static float ScaleFactor(NSView* view) {
return ui::GetScaleFactorScale(ui::GetScaleFactorForNativeView(view));
}
@@ -428,7 +452,7 @@ RenderWidgetHostViewMac::~RenderWidgetHostViewMac() {
UnlockMouse();
// Make sure that the layer doesn't reach into the now-invalid object.
- DestroyCompositedIOSurfaceAndLayer();
+ DestroyCompositedIOSurfaceAndLayer(kDestroyContext);
software_layer_.reset();
// We are owned by RenderWidgetHostViewCocoa, so if we go away before the
@@ -551,7 +575,8 @@ bool RenderWidgetHostViewMac::CreateCompositedIOSurfaceLayer() {
(compositing_iosurface_layer_ || !use_core_animation_);
}
-void RenderWidgetHostViewMac::DestroyCompositedIOSurfaceAndLayer() {
+void RenderWidgetHostViewMac::DestroyCompositedIOSurfaceAndLayer(
+ DestroyContextBehavior destroy_context_behavior) {
ScopedCAActionDisabler disabler;
compositing_iosurface_.reset();
@@ -561,8 +586,17 @@ void RenderWidgetHostViewMac::DestroyCompositedIOSurfaceAndLayer() {
[compositing_iosurface_layer_ disableCompositing];
compositing_iosurface_layer_.reset();
}
- ClearBoundContextDrawable();
- compositing_iosurface_context_ = NULL;
+ switch (destroy_context_behavior) {
+ case kLeaveContextBoundToView:
+ break;
+ case kDestroyContext:
+ ClearBoundContextDrawable();
+ compositing_iosurface_context_ = NULL;
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
}
void RenderWidgetHostViewMac::ClearBoundContextDrawable() {
@@ -1414,7 +1448,7 @@ bool RenderWidgetHostViewMac::DrawIOSurfaceWithoutCoreAnimation() {
void RenderWidgetHostViewMac::GotAcceleratedCompositingError() {
AckPendingSwapBuffers();
- DestroyCompositedIOSurfaceAndLayer();
+ DestroyCompositedIOSurfaceAndLayer(kDestroyContext);
// The existing GL contexts may be in a bad state, so don't re-use any of the
// existing ones anymore, rather, allocate new ones.
CompositingIOSurfaceContext::MarkExistingContextsAsNotShareable();
@@ -1616,7 +1650,7 @@ void RenderWidgetHostViewMac::AcceleratedSurfaceSuspend() {
}
void RenderWidgetHostViewMac::AcceleratedSurfaceRelease() {
- DestroyCompositedIOSurfaceAndLayer();
+ DestroyCompositedIOSurfaceAndLayer(kDestroyContext);
}
bool RenderWidgetHostViewMac::HasAcceleratedSurface(
@@ -1744,8 +1778,19 @@ void RenderWidgetHostViewMac::GotSoftwareFrame() {
AckPendingSwapBuffers();
- // Forget IOSurface since we are drawing a software frame now.
- DestroyCompositedIOSurfaceAndLayer();
+ // If overlapping views are allowed, then don't unbind the context
+ // from the view (that is, don't call clearDrawble -- just delete the
+ // texture and IOSurface). Rather, let it sit behind the software frame
+ // that will be put up in front. This will prevent transparent
+ // flashes.
+ // http://crbug.com/154531
+ // Also note that it is necessary that clearDrawable be called if
+ // overlapping views are not allowed, e.g, for content shell.
+ // http://crbug.com/178408
+ if (allow_overlapping_views_)
+ DestroyCompositedIOSurfaceAndLayer(kLeaveContextBoundToView);
+ else
+ DestroyCompositedIOSurfaceAndLayer(kDestroyContext);
}
}
@@ -2431,7 +2476,8 @@ void RenderWidgetHostViewMac::FrameSwapped() {
// Backing property notifications crash on 10.6 when building with the 10.7
// SDK, see http://crbug.com/260595.
- BOOL supportsBackingPropertiesNotification = base::mac::IsOSLionOrLater();
+ static BOOL supportsBackingPropertiesNotification =
+ SupportsBackingPropertiesChangedNotification();
if (oldWindow) {
if (supportsBackingPropertiesNotification) {
diff --git a/content/browser/renderer_host/render_widget_host_view_win.cc b/content/browser/renderer_host/render_widget_host_view_win.cc
index 50a658aa51..563ea65a85 100644
--- a/content/browser/renderer_host/render_widget_host_view_win.cc
+++ b/content/browser/renderer_host/render_widget_host_view_win.cc
@@ -48,6 +48,7 @@
#include "content/public/browser/native_web_keyboard_event.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
+#include "content/public/browser/render_view_host.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/page_zoom.h"
#include "content/public/common/process_type.h"
@@ -62,6 +63,7 @@
#include "ui/base/l10n/l10n_util_win.h"
#include "ui/base/text/text_elider.h"
#include "ui/base/touch/touch_device.h"
+#include "ui/base/touch/touch_enabled.h"
#include "ui/base/ui_base_switches.h"
#include "ui/base/view_prop.h"
#include "ui/base/win/dpi.h"
@@ -407,7 +409,7 @@ RenderWidgetHostViewWin::RenderWidgetHostViewWin(RenderWidgetHost* widget)
touch_state_(new WebTouchState(this)),
pointer_down_context_(false),
last_touch_location_(-1, -1),
- touch_events_enabled_(false),
+ touch_events_enabled_(ui::AreTouchEventsEnabled()),
gesture_recognizer_(ui::GestureRecognizer::Create(this)) {
render_widget_host_->SetView(this);
registrar_.Add(this,
@@ -608,8 +610,10 @@ bool RenderWidgetHostViewWin::HasFocus() const {
}
bool RenderWidgetHostViewWin::IsSurfaceAvailableForCopy() const {
- return !!render_widget_host_->GetBackingStore(false) ||
- (accelerated_surface_.get() && accelerated_surface_->IsReadyForCopy());
+ if (render_widget_host_->is_accelerated_compositing_active())
+ return accelerated_surface_.get() && accelerated_surface_->IsReadyForCopy();
+ else
+ return !!render_widget_host_->GetBackingStore(false);
}
void RenderWidgetHostViewWin::Show() {
@@ -926,35 +930,10 @@ void RenderWidgetHostViewWin::ProcessAckedTouchEvent(
void RenderWidgetHostViewWin::UpdateDesiredTouchMode() {
// Make sure that touch events even make sense.
- CommandLine* cmdline = CommandLine::ForCurrentProcess();
- static bool touch_mode = base::win::GetVersion() >= base::win::VERSION_WIN7 &&
- ui::IsTouchDevicePresent() && (
- !cmdline->HasSwitch(switches::kTouchEvents) ||
- cmdline->GetSwitchValueASCII(switches::kTouchEvents) !=
- switches::kTouchEventsDisabled);
-
- if (!touch_mode)
+ if (base::win::GetVersion() < base::win::VERSION_WIN7)
return;
-
- // Now we know that the window's current state doesn't match the desired
- // state. If we want touch mode, then we attempt to register for touch
- // events, and otherwise to unregister.
- touch_events_enabled_ = RegisterTouchWindow(m_hWnd, TWF_WANTPALM) == TRUE;
-
- if (!touch_events_enabled_) {
- UnregisterTouchWindow(m_hWnd);
- // Single finger panning is consistent with other windows applications.
- const DWORD gesture_allow = GC_PAN_WITH_SINGLE_FINGER_VERTICALLY |
- GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY;
- const DWORD gesture_block = GC_PAN_WITH_GUTTER;
- GESTURECONFIG gc[] = {
- { GID_ZOOM, GC_ZOOM, 0 },
- { GID_PAN, gesture_allow , gesture_block},
- { GID_TWOFINGERTAP, GC_TWOFINGERTAP , 0},
- { GID_PRESSANDTAP, GC_PRESSANDTAP , 0}
- };
- if (!SetGestureConfig(m_hWnd, 0, arraysize(gc), gc, sizeof(GESTURECONFIG)))
- NOTREACHED();
+ if (touch_events_enabled_) {
+ CHECK(RegisterTouchWindow(m_hWnd, TWF_WANTPALM));
}
}
@@ -2333,8 +2312,6 @@ LRESULT RenderWidgetHostViewWin::OnGestureEvent(
UINT message, WPARAM wparam, LPARAM lparam, BOOL& handled) {
TRACE_EVENT0("browser", "RenderWidgetHostViewWin::OnGestureEvent");
- // Note that as of M22, touch events are enabled by default on Windows.
- // This code should not be reachable.
DCHECK(!touch_events_enabled_);
handled = FALSE;
diff --git a/content/browser/renderer_host/ui_events_helper.cc b/content/browser/renderer_host/ui_events_helper.cc
index 89c09794f2..afbbf99017 100644
--- a/content/browser/renderer_host/ui_events_helper.cc
+++ b/content/browser/renderer_host/ui_events_helper.cc
@@ -237,6 +237,12 @@ 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/content/browser/resources/media/new/integration_test.html b/content/browser/resources/media/new/integration_test.html
new file mode 100644
index 0000000000..3a5225cb64
--- /dev/null
+++ b/content/browser/resources/media/new/integration_test.html
@@ -0,0 +1,86 @@
+<!--
+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.
+-->
+<!DOCTYPE html>
+<html>
+ <head>
+ <script src="webui_resource_test.js"></script>
+ <script src="util.js"></script>
+ <script src="player_manager.js"></script>
+ <script src="player_info.js"></script>
+ <script src="main.js"></script>
+ </head>
+ <body>
+ <script>
+ window.setUp = function() {
+ var doNothing = function() {};
+ var mockRenderer = {
+ redrawList: doNothing,
+ update: doNothing,
+ select: doNothing
+ };
+
+ var manager = new PlayerManager(mockRenderer);
+ media.initialize(manager);
+
+ window.playerManager = manager;
+ };
+
+ // The renderer and player ids are completely arbitrarily.
+ var TEST_RENDERER = 12;
+ var TEST_PLAYER = 4;
+ var TEST_NAME = TEST_RENDERER + ':' + TEST_PLAYER;
+
+ // Correctly use the information from a media event.
+ window.testOnMediaEvent = function() {
+ var event = {
+ ticksMillis: 132,
+ renderer: TEST_RENDERER,
+ player: TEST_PLAYER,
+ params: {
+ fps: 60,
+ other: 'hi'
+ }
+ };
+
+ window.media.onMediaEvent(event);
+ var info = window.playerManager.players_[TEST_NAME];
+
+ assertEquals(event.ticksMillis, info.firstTimestamp_);
+ assertEquals(TEST_NAME, info.id);
+ assertEquals(event.params.fps, info.properties.fps);
+ };
+
+ // Remove a player.
+ window.testOnRenderTerminated = function() {
+ window.testOnMediaEvent();
+
+ window.playerManager.shouldRemovePlayer_ = function() {
+ return true;
+ };
+
+ window.media.onRendererTerminated(TEST_RENDERER);
+ assertEquals(undefined, window.playerManager.players_[TEST_NAME]);
+ };
+
+ // Audio Streams are weird, they are handled separately
+ window.testAddAudioStream = function() {
+ var event = {
+ id: 'ID',
+ status: 'created',
+ playing: true
+ };
+
+ window.media.addAudioStream(event);
+
+ var player = window.playerManager.players_[event.id];
+ assertTrue(undefined !== player);
+ assertEquals(event.playing, player.properties['playing']);
+ };
+
+ runTests();
+ </script>
+ </body>
+</html>
diff --git a/content/browser/resources/media/new/main.js b/content/browser/resources/media/new/main.js
new file mode 100644
index 0000000000..61f6407bcf
--- /dev/null
+++ b/content/browser/resources/media/new/main.js
@@ -0,0 +1,134 @@
+// 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.
+
+/**
+ * A global object that gets used by the C++ interface.
+ */
+var media = (function() {
+ 'use strict';
+
+ var manager = null;
+
+ /**
+ * Users of |media| must call initialize prior to calling other methods.
+ */
+ function initialize(playerManager) {
+ manager = playerManager;
+ }
+
+ /**
+ * Call to modify or add a system property.
+ */
+ function onSystemProperty(timestamp, key, value) {
+ console.log('System properties not yet implemented');
+ }
+
+ /**
+ * Call to modify or add a property on a player.
+ */
+ function onPlayerProperty(id, timestamp, key, value) {
+ manager.updatePlayerInfo(id, timestamp, key, value);
+ }
+
+ function onPlayerPropertyNoRecord(id, timestamp, key, value) {
+ manager.updatePlayerInfoNoRecord(id, timestamp, key, value);
+ }
+
+ /**
+ * Call to add a player.
+ */
+ function onPlayerOpen(id, timestamp) {
+ manager.addPlayer(id, timestamp);
+ }
+
+ /**
+ * Call to remove a player.
+ */
+ function onPlayerClose(id) {
+ manager.removePlayer(id);
+ }
+
+ var media = {
+ onSystemProperty: onSystemProperty,
+ onPlayerProperty: onPlayerProperty,
+ onPlayerPropertyNoRecord: onPlayerPropertyNoRecord,
+ onPlayerOpen: onPlayerOpen,
+ onPlayerClose: onPlayerClose,
+
+ initialize: initialize
+ };
+
+ // Everything beyond this point is for backwards compatibility reasons.
+ // It will go away when the backend is updated.
+
+ media.onNetUpdate = function(update) {
+ // TODO(tyoverby): Implement
+ };
+
+ media.onRendererTerminated = function(renderId) {
+ util.object.forEach(manager.players_, function(playerInfo, id) {
+ if (playerInfo.properties['render_id'] == renderId) {
+ media.onPlayerClose(id);
+ }
+ });
+ };
+
+ // For whatever reason, addAudioStream is also called on
+ // the removal of audio streams.
+ media.addAudioStream = function(event) {
+ switch (event.status) {
+ case 'created':
+ media.onPlayerOpen(event.id);
+ // We have to simulate the timestamp since it isn't provided to us.
+ media.onPlayerProperty(
+ event.id, (new Date()).getTime(), 'playing', event.playing);
+ break;
+ case 'closed':
+ media.onPlayerClose(event.id);
+ break;
+ }
+ };
+ media.onItemDeleted = function() {
+ // This only gets called when an audio stream is removed, which
+ // for whatever reason is also handled by addAudioStream...
+ // Because it is already handled, we can safely ignore it.
+ };
+
+ media.onMediaEvent = function(event) {
+ var source = event.renderer + ':' + event.player;
+
+ // Although this gets called on every event, there is nothing we can do
+ // about this because there is no onOpen event.
+ media.onPlayerOpen(source);
+ media.onPlayerPropertyNoRecord(
+ source, event.ticksMillis, 'render_id', event.renderer);
+ media.onPlayerPropertyNoRecord(
+ source, event.ticksMillis, 'player_id', event.player);
+
+ var propertyCount = 0;
+ util.object.forEach(event.params, function(value, key) {
+ key = key.trim();
+
+ // These keys get spammed *a lot*, so put them on the display
+ // but don't log list.
+ if (key === 'buffer_start' ||
+ key === 'buffer_end' ||
+ key === 'buffer_current' ||
+ key === 'is_downloading_data') {
+ media.onPlayerPropertyNoRecord(
+ source, event.ticksMillis, key, value);
+ } else {
+ media.onPlayerProperty(source, event.ticksMillis, key, value);
+ }
+ propertyCount += 1;
+ });
+
+ if (propertyCount === 0) {
+ media.onPlayerProperty(
+ source, event.ticksMillis, 'EVENT', event.type);
+ }
+ };
+
+ return media;
+}());
diff --git a/content/browser/resources/media/new/util.js b/content/browser/resources/media/new/util.js
new file mode 100644
index 0000000000..5909e9ee1e
--- /dev/null
+++ b/content/browser/resources/media/new/util.js
@@ -0,0 +1,34 @@
+// 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.
+
+/**
+ * @fileoverview Some utility functions that don't belong anywhere else in the
+ * code.
+ */
+
+var util = (function() {
+ var util = {};
+ util.object = {};
+ /**
+ * Calls a function for each element in an object/map/hash.
+ *
+ * @param obj The object to iterate over.
+ * @param f The function to call on every value in the object. F should have
+ * the following arguments: f(value, key, object) where value is the value
+ * of the property, key is the corresponding key, and obj is the object that
+ * was passed in originally.
+ * @param optObj The object use as 'this' within f.
+ */
+ util.object.forEach = function(obj, f, optObj) {
+ 'use strict';
+ var key;
+ for (key in obj) {
+ if (obj.hasOwnProperty(key)) {
+ f.call(optObj, obj[key], key, obj);
+ }
+ }
+ };
+
+ return util;
+}());
diff --git a/content/browser/ssl/ssl_host_state.cc b/content/browser/ssl/ssl_host_state.cc
index c2fc06da1b..06c600205f 100644
--- a/content/browser/ssl/ssl_host_state.cc
+++ b/content/browser/ssl/ssl_host_state.cc
@@ -39,17 +39,19 @@ bool SSLHostState::DidHostRunInsecureContent(const std::string& host,
}
void SSLHostState::DenyCertForHost(net::X509Certificate* cert,
- const std::string& host) {
+ const std::string& host,
+ net::CertStatus error) {
DCHECK(CalledOnValidThread());
- cert_policy_for_host_[host].Deny(cert);
+ cert_policy_for_host_[host].Deny(cert, error);
}
void SSLHostState::AllowCertForHost(net::X509Certificate* cert,
- const std::string& host) {
+ const std::string& host,
+ net::CertStatus error) {
DCHECK(CalledOnValidThread());
- cert_policy_for_host_[host].Allow(cert);
+ cert_policy_for_host_[host].Allow(cert, error);
}
void SSLHostState::Clear() {
@@ -58,11 +60,12 @@ void SSLHostState::Clear() {
cert_policy_for_host_.clear();
}
-net::CertPolicy::Judgment SSLHostState::QueryPolicy(
- net::X509Certificate* cert, const std::string& host) {
+net::CertPolicy::Judgment SSLHostState::QueryPolicy(net::X509Certificate* cert,
+ const std::string& host,
+ net::CertStatus error) {
DCHECK(CalledOnValidThread());
- return cert_policy_for_host_[host].Check(cert);
+ return cert_policy_for_host_[host].Check(cert, error);
}
} // namespace content
diff --git a/content/browser/ssl/ssl_host_state.h b/content/browser/ssl/ssl_host_state.h
index b229b79b3d..820821786d 100644
--- a/content/browser/ssl/ssl_host_state.h
+++ b/content/browser/ssl/ssl_host_state.h
@@ -14,6 +14,7 @@
#include "base/supports_user_data.h"
#include "base/threading/non_thread_safe.h"
#include "content/common/content_export.h"
+#include "net/cert/cert_status_flags.h"
#include "net/cert/x509_certificate.h"
namespace content {
@@ -42,18 +43,25 @@ class CONTENT_EXPORT SSLHostState
// Returns whether the specified host ran insecure content.
bool DidHostRunInsecureContent(const std::string& host, int pid) const;
- // Records that |cert| is permitted to be used for |host| in the future.
- void DenyCertForHost(net::X509Certificate* cert, const std::string& host);
+ // Records that |cert| is not permitted to be used for |host| in the future,
+ // for a specified |error| type..
+ void DenyCertForHost(net::X509Certificate* cert,
+ const std::string& host,
+ net::CertStatus error);
- // Records that |cert| is not permitted to be used for |host| in the future.
- void AllowCertForHost(net::X509Certificate* cert, const std::string& host);
+ // Records that |cert| is permitted to be used for |host| in the future, for
+ // a specified |error| type.
+ void AllowCertForHost(net::X509Certificate* cert,
+ const std::string& host,
+ net::CertStatus error);
// Clear all allow/deny preferences.
void Clear();
- // Queries whether |cert| is allowed or denied for |host|.
- net::CertPolicy::Judgment QueryPolicy(
- net::X509Certificate* cert, const std::string& host);
+ // Queries whether |cert| is allowed or denied for |host| and |error|.
+ net::CertPolicy::Judgment QueryPolicy(net::X509Certificate* cert,
+ const std::string& host,
+ net::CertStatus error);
private:
// A BrokenHostEntry is a pair of (host, process_id) that indicates the host
diff --git a/content/browser/ssl/ssl_host_state_unittest.cc b/content/browser/ssl/ssl_host_state_unittest.cc
index 7ba266b09f..5e4366d375 100644
--- a/content/browser/ssl/ssl_host_state_unittest.cc
+++ b/content/browser/ssl/ssl_host_state_unittest.cc
@@ -120,48 +120,84 @@ TEST_F(SSLHostStateTest, QueryPolicy) {
SSLHostState state;
- EXPECT_EQ(state.QueryPolicy(google_cert.get(), "www.google.com"),
- net::CertPolicy::UNKNOWN);
- EXPECT_EQ(state.QueryPolicy(google_cert.get(), "google.com"),
- net::CertPolicy::UNKNOWN);
- EXPECT_EQ(state.QueryPolicy(google_cert.get(), "example.com"),
- net::CertPolicy::UNKNOWN);
-
- state.AllowCertForHost(google_cert.get(), "www.google.com");
-
- EXPECT_EQ(state.QueryPolicy(google_cert.get(), "www.google.com"),
- net::CertPolicy::ALLOWED);
- EXPECT_EQ(state.QueryPolicy(google_cert.get(), "google.com"),
- net::CertPolicy::UNKNOWN);
- EXPECT_EQ(state.QueryPolicy(google_cert.get(), "example.com"),
- net::CertPolicy::UNKNOWN);
-
- state.AllowCertForHost(google_cert.get(), "example.com");
-
- EXPECT_EQ(state.QueryPolicy(google_cert.get(), "www.google.com"),
- net::CertPolicy::ALLOWED);
- EXPECT_EQ(state.QueryPolicy(google_cert.get(), "google.com"),
- net::CertPolicy::UNKNOWN);
- EXPECT_EQ(state.QueryPolicy(google_cert.get(), "example.com"),
- net::CertPolicy::ALLOWED);
-
- state.DenyCertForHost(google_cert.get(), "example.com");
-
- EXPECT_EQ(state.QueryPolicy(google_cert.get(), "www.google.com"),
- net::CertPolicy::ALLOWED);
- EXPECT_EQ(state.QueryPolicy(google_cert.get(), "google.com"),
- net::CertPolicy::UNKNOWN);
- EXPECT_EQ(state.QueryPolicy(google_cert.get(), "example.com"),
- net::CertPolicy::DENIED);
+ EXPECT_EQ(net::CertPolicy::UNKNOWN,
+ state.QueryPolicy(google_cert.get(),
+ "www.google.com",
+ net::CERT_STATUS_DATE_INVALID));
+ EXPECT_EQ(net::CertPolicy::UNKNOWN,
+ state.QueryPolicy(google_cert.get(),
+ "google.com",
+ net::CERT_STATUS_DATE_INVALID));
+ EXPECT_EQ(net::CertPolicy::UNKNOWN,
+ state.QueryPolicy(google_cert.get(),
+ "example.com",
+ net::CERT_STATUS_DATE_INVALID));
+
+ state.AllowCertForHost(google_cert.get(),
+ "www.google.com",
+ net::CERT_STATUS_DATE_INVALID);
+
+ EXPECT_EQ(net::CertPolicy::ALLOWED,
+ state.QueryPolicy(google_cert.get(),
+ "www.google.com",
+ net::CERT_STATUS_DATE_INVALID));
+ EXPECT_EQ(net::CertPolicy::UNKNOWN,
+ state.QueryPolicy(google_cert.get(),
+ "google.com",
+ net::CERT_STATUS_DATE_INVALID));
+ EXPECT_EQ(net::CertPolicy::UNKNOWN,
+ state.QueryPolicy(google_cert.get(),
+ "example.com",
+ net::CERT_STATUS_DATE_INVALID));
+
+ state.AllowCertForHost(google_cert.get(),
+ "example.com",
+ net::CERT_STATUS_DATE_INVALID);
+
+ EXPECT_EQ(net::CertPolicy::ALLOWED,
+ state.QueryPolicy(google_cert.get(),
+ "www.google.com",
+ net::CERT_STATUS_DATE_INVALID));
+ EXPECT_EQ(net::CertPolicy::UNKNOWN,
+ state.QueryPolicy(google_cert.get(),
+ "google.com",
+ net::CERT_STATUS_DATE_INVALID));
+ EXPECT_EQ(net::CertPolicy::ALLOWED,
+ state.QueryPolicy(google_cert.get(),
+ "example.com",
+ net::CERT_STATUS_DATE_INVALID));
+
+ state.DenyCertForHost(google_cert.get(),
+ "example.com",
+ net::CERT_STATUS_DATE_INVALID);
+
+ EXPECT_EQ(net::CertPolicy::ALLOWED,
+ state.QueryPolicy(google_cert.get(),
+ "www.google.com",
+ net::CERT_STATUS_DATE_INVALID));
+ EXPECT_EQ(net::CertPolicy::UNKNOWN,
+ state.QueryPolicy(google_cert.get(),
+ "google.com",
+ net::CERT_STATUS_DATE_INVALID));
+ EXPECT_EQ(net::CertPolicy::DENIED,
+ state.QueryPolicy(google_cert.get(),
+ "example.com",
+ net::CERT_STATUS_DATE_INVALID));
state.Clear();
- EXPECT_EQ(state.QueryPolicy(google_cert.get(), "www.google.com"),
- net::CertPolicy::UNKNOWN);
- EXPECT_EQ(state.QueryPolicy(google_cert.get(), "google.com"),
- net::CertPolicy::UNKNOWN);
- EXPECT_EQ(state.QueryPolicy(google_cert.get(), "example.com"),
- net::CertPolicy::UNKNOWN);
+ EXPECT_EQ(net::CertPolicy::UNKNOWN,
+ state.QueryPolicy(google_cert.get(),
+ "www.google.com",
+ net::CERT_STATUS_DATE_INVALID));
+ EXPECT_EQ(net::CertPolicy::UNKNOWN,
+ state.QueryPolicy(google_cert.get(),
+ "google.com",
+ net::CERT_STATUS_DATE_INVALID));
+ EXPECT_EQ(net::CertPolicy::UNKNOWN,
+ state.QueryPolicy(google_cert.get(),
+ "example.com",
+ net::CERT_STATUS_DATE_INVALID));
}
} // namespace content
diff --git a/content/browser/ssl/ssl_policy.cc b/content/browser/ssl/ssl_policy.cc
index ec55736e7e..02af3983bf 100644
--- a/content/browser/ssl/ssl_policy.cc
+++ b/content/browser/ssl/ssl_policy.cc
@@ -34,7 +34,9 @@ SSLPolicy::SSLPolicy(SSLPolicyBackend* backend)
void SSLPolicy::OnCertError(SSLCertErrorHandler* handler) {
// First we check if we know the policy for this error.
net::CertPolicy::Judgment judgment = backend_->QueryPolicy(
- handler->ssl_info().cert.get(), handler->request_url().host());
+ handler->ssl_info().cert.get(),
+ handler->request_url().host(),
+ handler->cert_error());
if (judgment == net::CertPolicy::ALLOWED) {
handler->ContinueRequest();
@@ -138,6 +140,8 @@ void SSLPolicy::UpdateEntry(NavigationEntryImpl* entry,
if (web_contents->DisplayedInsecureContent())
entry->GetSSL().content_status |= SSLStatus::DISPLAYED_INSECURE_CONTENT;
+ else
+ entry->GetSSL().content_status &= ~SSLStatus::DISPLAYED_INSECURE_CONTENT;
}
void SSLPolicy::OnAllowCertificate(scoped_refptr<SSLCertErrorHandler> handler,
@@ -154,7 +158,8 @@ void SSLPolicy::OnAllowCertificate(scoped_refptr<SSLCertErrorHandler> handler,
// ContinueRequest() gets posted to a different thread. Calling
// AllowCertForHost() first ensures deterministic ordering.
backend_->AllowCertForHost(handler->ssl_info().cert.get(),
- handler->request_url().host());
+ handler->request_url().host(),
+ handler->cert_error());
handler->ContinueRequest();
} else {
// Default behavior for rejecting a certificate.
@@ -163,7 +168,8 @@ void SSLPolicy::OnAllowCertificate(scoped_refptr<SSLCertErrorHandler> handler,
// CancelRequest() gets posted to a different thread. Calling
// DenyCertForHost() first ensures deterministic ordering.
backend_->DenyCertForHost(handler->ssl_info().cert.get(),
- handler->request_url().host());
+ handler->request_url().host(),
+ handler->cert_error());
handler->CancelRequest();
}
}
diff --git a/content/browser/ssl/ssl_policy_backend.cc b/content/browser/ssl/ssl_policy_backend.cc
index 8aa8bc7117..57e05702c8 100644
--- a/content/browser/ssl/ssl_policy_backend.cc
+++ b/content/browser/ssl/ssl_policy_backend.cc
@@ -27,18 +27,22 @@ bool SSLPolicyBackend::DidHostRunInsecureContent(const std::string& host,
}
void SSLPolicyBackend::DenyCertForHost(net::X509Certificate* cert,
- const std::string& host) {
- ssl_host_state_->DenyCertForHost(cert, host);
+ const std::string& host,
+ net::CertStatus error) {
+ ssl_host_state_->DenyCertForHost(cert, host, error);
}
void SSLPolicyBackend::AllowCertForHost(net::X509Certificate* cert,
- const std::string& host) {
- ssl_host_state_->AllowCertForHost(cert, host);
+ const std::string& host,
+ net::CertStatus error) {
+ ssl_host_state_->AllowCertForHost(cert, host, error);
}
net::CertPolicy::Judgment SSLPolicyBackend::QueryPolicy(
- net::X509Certificate* cert, const std::string& host) {
- return ssl_host_state_->QueryPolicy(cert, host);
+ net::X509Certificate* cert,
+ const std::string& host,
+ net::CertStatus error) {
+ return ssl_host_state_->QueryPolicy(cert, host, error);
}
} // namespace content
diff --git a/content/browser/ssl/ssl_policy_backend.h b/content/browser/ssl/ssl_policy_backend.h
index 18ec580356..06ea23eccc 100644
--- a/content/browser/ssl/ssl_policy_backend.h
+++ b/content/browser/ssl/ssl_policy_backend.h
@@ -10,6 +10,7 @@
#include "base/basictypes.h"
#include "base/strings/string16.h"
+#include "net/cert/cert_status_flags.h"
#include "net/cert/x509_certificate.h"
namespace content {
@@ -26,15 +27,22 @@ class SSLPolicyBackend {
// Returns whether the specified host ran insecure content.
bool DidHostRunInsecureContent(const std::string& host, int pid) const;
- // Records that |cert| is permitted to be used for |host| in the future.
- void DenyCertForHost(net::X509Certificate* cert, const std::string& host);
+ // Records that |cert| is not permitted to be used for |host| in the future,
+ // for a specific error type.
+ void DenyCertForHost(net::X509Certificate* cert,
+ const std::string& host,
+ net::CertStatus error);
- // Records that |cert| is not permitted to be used for |host| in the future.
- void AllowCertForHost(net::X509Certificate* cert, const std::string& host);
+ // Records that |cert| is permitted to be used for |host| in the future, for
+ // a specific error type.
+ void AllowCertForHost(net::X509Certificate* cert,
+ const std::string& host,
+ net::CertStatus error);
// Queries whether |cert| is allowed or denied for |host|.
- net::CertPolicy::Judgment QueryPolicy(
- net::X509Certificate* cert, const std::string& host);
+ net::CertPolicy::Judgment QueryPolicy(net::X509Certificate* cert,
+ const std::string& host,
+ net::CertStatus error);
private:
// SSL state specific for each host.
diff --git a/content/browser/startup_task_runner.cc b/content/browser/startup_task_runner.cc
new file mode 100644
index 0000000000..a7e730e5d8
--- /dev/null
+++ b/content/browser/startup_task_runner.cc
@@ -0,0 +1,63 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/startup_task_runner.h"
+
+#include "base/bind.h"
+#include "base/location.h"
+#include "base/message_loop/message_loop.h"
+
+namespace content {
+
+StartupTaskRunner::StartupTaskRunner(
+ bool browser_may_start_asynchronously,
+ base::Callback<void(int)> const startup_complete_callback,
+ scoped_refptr<base::SingleThreadTaskRunner> proxy)
+ : asynchronous_startup_(browser_may_start_asynchronously),
+ startup_complete_callback_(startup_complete_callback),
+ proxy_(proxy) {}
+
+void StartupTaskRunner::AddTask(StartupTask& callback) {
+ task_list_.push_back(callback);
+}
+
+void StartupTaskRunner::StartRunningTasks() {
+ DCHECK(proxy_);
+ int result = 0;
+ if (asynchronous_startup_ && !task_list_.empty()) {
+ const base::Closure next_task =
+ base::Bind(&StartupTaskRunner::WrappedTask, this);
+ proxy_->PostNonNestableTask(FROM_HERE, next_task);
+ } else {
+ for (std::list<StartupTask>::iterator it = task_list_.begin();
+ it != task_list_.end();
+ it++) {
+ result = it->Run();
+ if (result > 0) {
+ break;
+ }
+ }
+ if (!startup_complete_callback_.is_null()) {
+ startup_complete_callback_.Run(result);
+ }
+ }
+}
+
+void StartupTaskRunner::WrappedTask() {
+ int result = task_list_.front().Run();
+ task_list_.pop_front();
+ if (result > 0 || task_list_.empty()) {
+ if (!startup_complete_callback_.is_null()) {
+ startup_complete_callback_.Run(result);
+ }
+ } else {
+ const base::Closure next_task =
+ base::Bind(&StartupTaskRunner::WrappedTask, this);
+ proxy_->PostNonNestableTask(FROM_HERE, next_task);
+ }
+}
+
+StartupTaskRunner::~StartupTaskRunner() {}
+
+} // namespace content
diff --git a/content/browser/startup_task_runner.h b/content/browser/startup_task_runner.h
new file mode 100644
index 0000000000..5f954edc88
--- /dev/null
+++ b/content/browser/startup_task_runner.h
@@ -0,0 +1,66 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_STARTUP_TASK_RUNNER_H_
+#define CONTENT_BROWSER_STARTUP_TASK_RUNNER_H_
+
+#include <list>
+
+#include "base/callback.h"
+#include "base/memory/ref_counted.h"
+#include "base/single_thread_task_runner.h"
+
+#include "build/build_config.h"
+
+#include "content/public/browser/browser_main_runner.h"
+
+namespace content {
+
+// A startup task is a void function returning the status on completion.
+// a status of > 0 indicates a failure, and that no further startup tasks should
+// be run.
+typedef base::Callback<int(void)> StartupTask;
+
+// This class runs startup tasks. The tasks are either run immediately inline,
+// or are queued one at a time on the UI thread's message loop. If the events
+// are queued, UI events that are received during startup will be acted upon
+// between startup tasks. The motivation for this is that, on targets where the
+// UI is already started, it allows us to keep the UI responsive during startup.
+//
+// Note that this differs from a SingleThreadedTaskRunner in that there may be
+// no opportunity to handle UI events between the tasks of a
+// SingleThreadedTaskRunner.
+
+class CONTENT_EXPORT StartupTaskRunner
+ : public base::RefCounted<StartupTaskRunner> {
+
+ public:
+ // Constructor: Note that |startup_complete_callback| is optional. If it is
+ // not null it will be called once all the startup tasks have run.
+ StartupTaskRunner(bool browser_may_start_asynchronously,
+ base::Callback<void(int)> startup_complete_callback,
+ scoped_refptr<base::SingleThreadTaskRunner> proxy);
+
+ // Add a task to the queue of startup tasks to be run.
+ virtual void AddTask(StartupTask& callback);
+
+ // Start running the tasks.
+ virtual void StartRunningTasks();
+
+ private:
+ friend class base::RefCounted<StartupTaskRunner>;
+ virtual ~StartupTaskRunner();
+
+ std::list<StartupTask> task_list_;
+ void WrappedTask();
+
+ const bool asynchronous_startup_;
+ base::Callback<void(int)> startup_complete_callback_;
+ scoped_refptr<base::SingleThreadTaskRunner> proxy_;
+
+ DISALLOW_COPY_AND_ASSIGN(StartupTaskRunner);
+};
+
+} // namespace content
+#endif // CONTENT_BROWSER_STARTUP_TASK_RUNNER_H_
diff --git a/content/browser/startup_task_runner_unittest.cc b/content/browser/startup_task_runner_unittest.cc
new file mode 100644
index 0000000000..2efa79f7ac
--- /dev/null
+++ b/content/browser/startup_task_runner_unittest.cc
@@ -0,0 +1,281 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/startup_task_runner.h"
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/callback.h"
+#include "base/location.h"
+#include "base/run_loop.h"
+#include "base/task_runner.h"
+
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+namespace {
+
+using base::Closure;
+using testing::_;
+using testing::Assign;
+using testing::Invoke;
+using testing::WithArg;
+
+bool observer_called = false;
+int observer_result;
+base::Closure task;
+
+// I couldn't get gMock's SaveArg to compile, hence had to save the argument
+// this way
+bool SaveTaskArg(const Closure& arg) {
+ task = arg;
+ return true;
+}
+
+void Observer(int result) {
+ observer_called = true;
+ observer_result = result;
+}
+
+class StartupTaskRunnerTest : public testing::Test {
+ public:
+
+ virtual void SetUp() {
+ last_task_ = 0;
+ observer_called = false;
+ }
+
+ int Task1() {
+ last_task_ = 1;
+ return 0;
+ }
+
+ int Task2() {
+ last_task_ = 2;
+ return 0;
+ }
+
+ int FailingTask() {
+ // Task returning failure
+ last_task_ = 3;
+ return 1;
+ }
+
+ int GetLastTask() { return last_task_; }
+
+ private:
+
+ int last_task_;
+};
+
+// We can't use the real message loop, even if we want to, since doing so on
+// Android requires a complex Java infrastructure. The test would have to built
+// as a content_shell test; but content_shell startup invokes the class we are
+// trying to test.
+//
+// The mocks are not directly in TaskRunnerProxy because reference counted
+// objects seem to confuse the mocking framework
+
+class MockTaskRunner {
+ public:
+ MOCK_METHOD3(
+ PostDelayedTask,
+ bool(const tracked_objects::Location&, const Closure&, base::TimeDelta));
+ MOCK_METHOD3(
+ PostNonNestableDelayedTask,
+ bool(const tracked_objects::Location&, const Closure&, base::TimeDelta));
+};
+
+class TaskRunnerProxy : public base::SingleThreadTaskRunner {
+ public:
+ TaskRunnerProxy(MockTaskRunner* mock) : mock_(mock) {}
+ virtual bool RunsTasksOnCurrentThread() const OVERRIDE { return true; }
+ virtual bool PostDelayedTask(const tracked_objects::Location& location,
+ const Closure& closure,
+ base::TimeDelta delta) OVERRIDE {
+ return mock_->PostDelayedTask(location, closure, delta);
+ }
+ virtual bool PostNonNestableDelayedTask(
+ const tracked_objects::Location& location,
+ const Closure& closure,
+ base::TimeDelta delta) OVERRIDE {
+ return mock_->PostNonNestableDelayedTask(location, closure, delta);
+ }
+
+ private:
+ MockTaskRunner* mock_;
+ virtual ~TaskRunnerProxy() {}
+};
+
+TEST_F(StartupTaskRunnerTest, SynchronousExecution) {
+ MockTaskRunner mock_runner;
+ scoped_refptr<TaskRunnerProxy> proxy = new TaskRunnerProxy(&mock_runner);
+
+ EXPECT_CALL(mock_runner, PostDelayedTask(_, _, _)).Times(0);
+ EXPECT_CALL(mock_runner, PostNonNestableDelayedTask(_, _, _)).Times(0);
+
+ scoped_refptr<StartupTaskRunner> runner =
+ new StartupTaskRunner(false, base::Bind(&Observer), proxy);
+
+ StartupTask task1 =
+ base::Bind(&StartupTaskRunnerTest::Task1, base::Unretained(this));
+ runner->AddTask(task1);
+ EXPECT_EQ(GetLastTask(), 0);
+ StartupTask task2 =
+ base::Bind(&StartupTaskRunnerTest::Task2, base::Unretained(this));
+ runner->AddTask(task2);
+
+ // Nothing should run until we tell them to.
+ EXPECT_EQ(GetLastTask(), 0);
+ runner->StartRunningTasks();
+
+ // On an immediate StartupTaskRunner the tasks should now all have run.
+ EXPECT_EQ(GetLastTask(), 2);
+
+ EXPECT_TRUE(observer_called);
+ EXPECT_EQ(observer_result, 0);
+}
+
+TEST_F(StartupTaskRunnerTest, NullObserver) {
+ MockTaskRunner mock_runner;
+ scoped_refptr<TaskRunnerProxy> proxy = new TaskRunnerProxy(&mock_runner);
+
+ EXPECT_CALL(mock_runner, PostDelayedTask(_, _, _)).Times(0);
+ EXPECT_CALL(mock_runner, PostNonNestableDelayedTask(_, _, _)).Times(0);
+
+ scoped_refptr<StartupTaskRunner> runner =
+ new StartupTaskRunner(false, base::Callback<void(int)>(), proxy);
+
+ StartupTask task1 =
+ base::Bind(&StartupTaskRunnerTest::Task1, base::Unretained(this));
+ runner->AddTask(task1);
+ EXPECT_EQ(GetLastTask(), 0);
+ StartupTask task2 =
+ base::Bind(&StartupTaskRunnerTest::Task2, base::Unretained(this));
+ runner->AddTask(task2);
+
+ // Nothing should run until we tell them to.
+ EXPECT_EQ(GetLastTask(), 0);
+ runner->StartRunningTasks();
+
+ // On an immediate StartupTaskRunner the tasks should now all have run.
+ EXPECT_EQ(GetLastTask(), 2);
+
+ EXPECT_FALSE(observer_called);
+}
+
+TEST_F(StartupTaskRunnerTest, SynchronousExecutionFailedTask) {
+ MockTaskRunner mock_runner;
+ scoped_refptr<TaskRunnerProxy> proxy = new TaskRunnerProxy(&mock_runner);
+
+ EXPECT_CALL(mock_runner, PostDelayedTask(_, _, _)).Times(0);
+ EXPECT_CALL(mock_runner, PostNonNestableDelayedTask(_, _, _)).Times(0);
+
+ scoped_refptr<StartupTaskRunner> runner =
+ new StartupTaskRunner(false, base::Bind(&Observer), proxy);
+
+ StartupTask task3 =
+ base::Bind(&StartupTaskRunnerTest::FailingTask, base::Unretained(this));
+ runner->AddTask(task3);
+ EXPECT_EQ(GetLastTask(), 0);
+ StartupTask task2 =
+ base::Bind(&StartupTaskRunnerTest::Task2, base::Unretained(this));
+ runner->AddTask(task2);
+
+ // Nothing should run until we tell them to.
+ EXPECT_EQ(GetLastTask(), 0);
+ runner->StartRunningTasks();
+
+ // Only the first task should have run, since it failed
+ EXPECT_EQ(GetLastTask(), 3);
+
+ EXPECT_TRUE(observer_called);
+ EXPECT_EQ(observer_result, 1);
+}
+
+TEST_F(StartupTaskRunnerTest, AsynchronousExecution) {
+
+ MockTaskRunner mock_runner;
+ scoped_refptr<TaskRunnerProxy> proxy = new TaskRunnerProxy(&mock_runner);
+
+ EXPECT_CALL(mock_runner, PostDelayedTask(_, _, _)).Times(0);
+ EXPECT_CALL(
+ mock_runner,
+ PostNonNestableDelayedTask(_, _, base::TimeDelta::FromMilliseconds(0)))
+ .Times(testing::Between(2, 3))
+ .WillRepeatedly(WithArg<1>(Invoke(SaveTaskArg)));
+
+ scoped_refptr<StartupTaskRunner> runner =
+ new StartupTaskRunner(true, base::Bind(&Observer), proxy);
+
+ StartupTask task1 =
+ base::Bind(&StartupTaskRunnerTest::Task1, base::Unretained(this));
+ runner->AddTask(task1);
+ StartupTask task2 =
+ base::Bind(&StartupTaskRunnerTest::Task2, base::Unretained(this));
+ runner->AddTask(task2);
+
+ // Nothing should run until we tell them to.
+ EXPECT_EQ(GetLastTask(), 0);
+ runner->StartRunningTasks();
+
+ // No tasks should have run yet, since we the message loop hasn't run.
+ EXPECT_EQ(GetLastTask(), 0);
+
+ // Fake the actual message loop. Each time a task is run a new task should
+ // be added to the queue, hence updating "task". The loop should actually run
+ // at most 3 times (once for each task plus possibly once for the observer),
+ // the "4" is a backstop.
+ for (int i = 0; i < 4 && !observer_called; i++) {
+ task.Run();
+ EXPECT_EQ(i + 1, GetLastTask());
+ }
+ EXPECT_TRUE(observer_called);
+ EXPECT_EQ(observer_result, 0);
+}
+
+TEST_F(StartupTaskRunnerTest, AsynchronousExecutionFailedTask) {
+
+ MockTaskRunner mock_runner;
+ scoped_refptr<TaskRunnerProxy> proxy = new TaskRunnerProxy(&mock_runner);
+
+ EXPECT_CALL(mock_runner, PostDelayedTask(_, _, _)).Times(0);
+ EXPECT_CALL(
+ mock_runner,
+ PostNonNestableDelayedTask(_, _, base::TimeDelta::FromMilliseconds(0)))
+ .Times(testing::Between(1, 2))
+ .WillRepeatedly(WithArg<1>(Invoke(SaveTaskArg)));
+
+ scoped_refptr<StartupTaskRunner> runner =
+ new StartupTaskRunner(true, base::Bind(&Observer), proxy);
+
+ StartupTask task3 =
+ base::Bind(&StartupTaskRunnerTest::FailingTask, base::Unretained(this));
+ runner->AddTask(task3);
+ StartupTask task2 =
+ base::Bind(&StartupTaskRunnerTest::Task2, base::Unretained(this));
+ runner->AddTask(task2);
+
+ // Nothing should run until we tell them to.
+ EXPECT_EQ(GetLastTask(), 0);
+ runner->StartRunningTasks();
+
+ // No tasks should have run yet, since we the message loop hasn't run.
+ EXPECT_EQ(GetLastTask(), 0);
+
+ // Fake the actual message loop. Each time a task is run a new task should
+ // be added to the queue, hence updating "task". The loop should actually run
+ // at most twice (once for the failed task plus possibly once for the
+ // observer), the "4" is a backstop.
+ for (int i = 0; i < 4 && !observer_called; i++) {
+ task.Run();
+ }
+ EXPECT_EQ(GetLastTask(), 3);
+
+ EXPECT_TRUE(observer_called);
+ EXPECT_EQ(observer_result, 1);
+}
+} // namespace
+} // namespace content
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc
index ec092d20c1..f7cda5c428 100644
--- a/content/browser/storage_partition_impl.cc
+++ b/content/browser/storage_partition_impl.cc
@@ -26,132 +26,244 @@ namespace content {
namespace {
-void DoNothingStatusCallback(quota::QuotaStatusCode status) {
- // Do nothing.
+int GenerateQuotaClientMask(uint32 remove_mask) {
+ int quota_client_mask = 0;
+
+ if (remove_mask & StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS)
+ quota_client_mask |= quota::QuotaClient::kFileSystem;
+ if (remove_mask & StoragePartition::REMOVE_DATA_MASK_WEBSQL)
+ quota_client_mask |= quota::QuotaClient::kDatabase;
+ if (remove_mask & StoragePartition::REMOVE_DATA_MASK_APPCACHE)
+ quota_client_mask |= quota::QuotaClient::kAppcache;
+ if (remove_mask & StoragePartition::REMOVE_DATA_MASK_INDEXEDDB)
+ quota_client_mask |= quota::QuotaClient::kIndexedDatabase;
+
+ return quota_client_mask;
}
-void ClearQuotaManagedOriginsOnIOThread(
- const scoped_refptr<quota::QuotaManager>& quota_manager,
- const std::set<GURL>& origins,
- quota::StorageType quota_storage_type) {
- // The QuotaManager manages all storage other than cookies, LocalStorage,
- // and SessionStorage. This loop wipes out most HTML5 storage for the given
- // origins.
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- std::set<GURL>::const_iterator origin;
- for (std::set<GURL>::const_iterator origin = origins.begin();
- origin != origins.end(); ++origin) {
- quota_manager->DeleteOriginData(*origin, quota_storage_type,
- quota::QuotaClient::kAllClientsMask,
- base::Bind(&DoNothingStatusCallback));
+void OnClearedCookies(const base::Closure& callback, int num_deleted) {
+ // The final callback needs to happen from UI thread.
+ if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&OnClearedCookies, callback, num_deleted));
+ return;
}
+
+ callback.Run();
}
-void ClearOriginOnIOThread(
- uint32 storage_mask,
- const GURL& storage_origin,
- const scoped_refptr<net::URLRequestContextGetter>& request_context,
- const scoped_refptr<quota::QuotaManager>& quota_manager) {
+void ClearCookiesOnIOThread(
+ const scoped_refptr<net::URLRequestContextGetter>& rq_context,
+ const base::Time begin,
+ const base::Time end,
+ const base::Closure& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ net::CookieStore* cookie_store = rq_context->
+ GetURLRequestContext()->cookie_store();
+ cookie_store->DeleteAllCreatedBetweenAsync(begin, end,
+ base::Bind(&OnClearedCookies, callback));
+}
- if (storage_mask & StoragePartition::kCookies) {
- // Handle the cookies.
- net::CookieMonster* cookie_monster =
- request_context->GetURLRequestContext()->cookie_store()->
- GetCookieMonster();
- if (cookie_monster)
- cookie_monster->DeleteAllForHostAsync(
- storage_origin, net::CookieMonster::DeleteCallback());
+void OnQuotaManagedOriginDeleted(const GURL& origin,
+ quota::StorageType type,
+ size_t* origins_to_delete_count,
+ const base::Closure& callback,
+ quota::QuotaStatusCode status) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK_GT(*origins_to_delete_count, 0u);
+ if (status != quota::kQuotaStatusOk) {
+ DLOG(ERROR) << "Couldn't remove data of type " << type << " for origin "
+ << origin << ". Status: " << status;
}
- // Handle all HTML5 storage other than DOMStorageContext.
- std::set<GURL> origins;
- origins.insert(storage_origin);
- if (storage_mask & StoragePartition::kQuotaManagedTemporaryStorage) {
- ClearQuotaManagedOriginsOnIOThread(quota_manager,
- origins,
- quota::kStorageTypeTemporary);
- }
- if (storage_mask & StoragePartition::kQuotaManagedPersistentStorage) {
- ClearQuotaManagedOriginsOnIOThread(quota_manager,
- origins,
- quota::kStorageTypePersistent);
- }
- if (storage_mask & StoragePartition::kQuotaManagedSyncableStorage) {
- ClearQuotaManagedOriginsOnIOThread(quota_manager,
- origins,
- quota::kStorageTypeSyncable);
+ (*origins_to_delete_count)--;
+ if (*origins_to_delete_count == 0) {
+ delete origins_to_delete_count;
+ callback.Run();
}
}
-void ClearAllDataOnIOThread(
- uint32 storage_mask,
- const scoped_refptr<net::URLRequestContextGetter>& request_context,
- const scoped_refptr<quota::QuotaManager>& quota_manager) {
+void ClearQuotaManagedOriginsOnIOThread(quota::QuotaManager* quota_manager,
+ uint32 remove_mask,
+ const base::Closure& callback,
+ const std::set<GURL>& origins,
+ quota::StorageType quota_storage_type) {
+ // The QuotaManager manages all storage other than cookies, LocalStorage,
+ // and SessionStorage. This loop wipes out most HTML5 storage for the given
+ // origins.
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- if (storage_mask & StoragePartition::kCookies) {
- // Handle the cookies.
- net::CookieMonster* cookie_monster =
- request_context->GetURLRequestContext()->cookie_store()->
- GetCookieMonster();
- if (cookie_monster)
- cookie_monster->DeleteAllAsync(net::CookieMonster::DeleteCallback());
+ if (!origins.size()) {
+ // No origins to clear.
+ callback.Run();
+ return;
}
- // Handle all HTML5 storage other than DOMStorageContext.
- if (storage_mask & StoragePartition::kQuotaManagedTemporaryStorage) {
- quota_manager->GetOriginsModifiedSince(
- quota::kStorageTypeTemporary, base::Time(),
- base::Bind(&ClearQuotaManagedOriginsOnIOThread, quota_manager));
- }
- if (storage_mask & StoragePartition::kQuotaManagedPersistentStorage) {
- quota_manager->GetOriginsModifiedSince(
- quota::kStorageTypePersistent, base::Time(),
- base::Bind(&ClearQuotaManagedOriginsOnIOThread, quota_manager));
- }
- if (storage_mask & StoragePartition::kQuotaManagedSyncableStorage) {
- quota_manager->GetOriginsModifiedSince(
- quota::kStorageTypeSyncable, base::Time(),
- base::Bind(&ClearQuotaManagedOriginsOnIOThread, quota_manager));
+ std::set<GURL>::const_iterator origin;
+ size_t* origins_to_delete_count = new size_t(origins.size());
+ for (std::set<GURL>::const_iterator origin = origins.begin();
+ origin != origins.end(); ++origin) {
+ quota_manager->DeleteOriginData(
+ *origin, quota_storage_type,
+ GenerateQuotaClientMask(remove_mask),
+ base::Bind(&OnQuotaManagedOriginDeleted,
+ origin->GetOrigin(), quota_storage_type,
+ origins_to_delete_count, callback));
}
}
-void ClearedShaderCacheOnIOThread(base::Closure callback) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback);
+void ClearedShaderCache(const base::Closure& callback) {
+ if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&ClearedShaderCache, callback));
+ return;
+ }
+ callback.Run();
}
-void ClearShaderCacheOnIOThread(base::FilePath path,
- base::Time begin, base::Time end, base::Closure callback) {
+void ClearShaderCacheOnIOThread(const base::FilePath& path,
+ const base::Time begin,
+ const base::Time end,
+ const base::Closure& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
ShaderCacheFactory::GetInstance()->ClearByPath(
- path, begin, end,
- base::Bind(&ClearedShaderCacheOnIOThread, callback));
+ path, begin, end, base::Bind(&ClearedShaderCache, callback));
}
void OnLocalStorageUsageInfo(
const scoped_refptr<DOMStorageContextImpl>& dom_storage_context,
+ const base::Time delete_begin,
+ const base::Time delete_end,
+ const base::Closure& callback,
const std::vector<dom_storage::LocalStorageUsageInfo>& infos) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
for (size_t i = 0; i < infos.size(); ++i) {
- dom_storage_context->DeleteLocalStorage(infos[i].origin);
+ if (infos[i].last_modified >= delete_begin &&
+ infos[i].last_modified <= delete_end) {
+ dom_storage_context->DeleteLocalStorage(infos[i].origin);
+ }
}
+ callback.Run();
}
void OnSessionStorageUsageInfo(
const scoped_refptr<DOMStorageContextImpl>& dom_storage_context,
+ const base::Closure& callback,
const std::vector<dom_storage::SessionStorageUsageInfo>& infos) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- for (size_t i = 0; i < infos.size(); ++i) {
+ for (size_t i = 0; i < infos.size(); ++i)
dom_storage_context->DeleteSessionStorage(infos[i]);
+
+ callback.Run();
+}
+
+void ClearLocalStorageOnUIThread(
+ const scoped_refptr<DOMStorageContextImpl>& dom_storage_context,
+ const GURL& remove_origin,
+ const base::Time begin,
+ const base::Time end,
+ const base::Closure& callback) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ if (!remove_origin.is_empty()) {
+ dom_storage_context->DeleteLocalStorage(remove_origin);
+ callback.Run();
+ return;
}
+
+ dom_storage_context->GetLocalStorageUsage(
+ base::Bind(&OnLocalStorageUsageInfo,
+ dom_storage_context, begin, end, callback));
+}
+
+void ClearSessionStorageOnUIThread(
+ const scoped_refptr<DOMStorageContextImpl>& dom_storage_context,
+ const base::Closure& callback) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ dom_storage_context->GetSessionStorageUsage(
+ base::Bind(&OnSessionStorageUsageInfo, dom_storage_context, callback));
}
} // namespace
+// Helper for deleting quota managed data from a partition.
+//
+// Most of the operations in this class are done on IO thread.
+struct StoragePartitionImpl::QuotaManagedDataDeletionHelper {
+ QuotaManagedDataDeletionHelper(const base::Closure& callback)
+ : callback(callback), task_count(0) {
+ }
+
+ void IncrementTaskCountOnIO();
+ void DecrementTaskCountOnIO();
+
+ void ClearDataOnIOThread(
+ const scoped_refptr<quota::QuotaManager>& quota_manager,
+ const base::Time begin,
+ uint32 remove_mask,
+ uint32 quota_storage_remove_mask,
+ const GURL& remove_origin);
+
+ // Accessed on IO thread.
+ const base::Closure callback;
+ // Accessed on IO thread.
+ int task_count;
+};
+
+// Helper for deleting all sorts of data from a partition, keeps track of
+// deletion status.
+//
+// StoragePartitionImpl creates an instance of this class to keep track of
+// data deletion progress. Deletion requires deleting multiple bits of data
+// (e.g. cookies, local storage, session storage etc.) and hopping between UI
+// and IO thread. An instance of this class is created in the beginning of
+// deletion process (StoragePartitionImpl::ClearDataImpl) and the instance is
+// forwarded and updated on each (sub) deletion's callback. The instance is
+// finally destroyed when deletion completes (and |callback| is invoked).
+struct StoragePartitionImpl::DataDeletionHelper {
+ DataDeletionHelper(const base::Closure& callback)
+ : callback(callback), task_count(0) {
+ }
+
+ void IncrementTaskCountOnUI();
+ void DecrementTaskCountOnUI();
+
+ void ClearDataOnUIThread(uint32 remove_mask,
+ uint32 quota_storage_remove_mask,
+ const GURL& remove_origin,
+ const base::FilePath& path,
+ net::URLRequestContextGetter* rq_context,
+ DOMStorageContextImpl* dom_storage_context,
+ quota::QuotaManager* quota_manager,
+ const base::Time begin,
+ const base::Time end);
+
+ // Accessed on UI thread.
+ const base::Closure callback;
+ // Accessed on UI thread.
+ int task_count;
+};
+
+void ClearQuotaManagedDataOnIOThread(
+ const scoped_refptr<quota::QuotaManager>& quota_manager,
+ const base::Time begin,
+ uint32 remove_mask,
+ uint32 quota_storage_remove_mask,
+ const GURL& remove_origin,
+ const base::Closure& callback) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ StoragePartitionImpl::QuotaManagedDataDeletionHelper* helper =
+ new StoragePartitionImpl::QuotaManagedDataDeletionHelper(callback);
+ helper->ClearDataOnIOThread(quota_manager, begin,
+ remove_mask, quota_storage_remove_mask, remove_origin);
+}
+
StoragePartitionImpl::StoragePartitionImpl(
const base::FilePath& partition_path,
quota::QuotaManager* quota_manager,
@@ -293,59 +405,221 @@ IndexedDBContextImpl* StoragePartitionImpl::GetIndexedDBContext() {
return indexed_db_context_.get();
}
-void StoragePartitionImpl::AsyncClearDataForOrigin(
- uint32 storage_mask,
- const GURL& storage_origin,
- net::URLRequestContextGetter* request_context_getter) {
+void StoragePartitionImpl::ClearDataImpl(
+ uint32 remove_mask,
+ uint32 quota_storage_remove_mask,
+ const GURL& remove_origin,
+ net::URLRequestContextGetter* rq_context,
+ const base::Time begin,
+ const base::Time end,
+ const base::Closure& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DataDeletionHelper* helper = new DataDeletionHelper(callback);
+ // |helper| deletes itself when done in
+ // DataDeletionHelper::DecrementTaskCountOnUI().
+ helper->ClearDataOnUIThread(
+ remove_mask, quota_storage_remove_mask, remove_origin,
+ GetPath(), rq_context, dom_storage_context_, quota_manager_, begin, end);
+}
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::Bind(&ClearOriginOnIOThread,
- storage_mask,
- storage_origin,
- make_scoped_refptr(request_context_getter),
- quota_manager_));
+void StoragePartitionImpl::
+ QuotaManagedDataDeletionHelper::IncrementTaskCountOnIO() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ ++task_count;
+}
+
+void StoragePartitionImpl::
+ QuotaManagedDataDeletionHelper::DecrementTaskCountOnIO() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK_GT(task_count, 0);
+ --task_count;
+ if (task_count)
+ return;
- if (storage_mask & kLocalDomStorage)
- GetDOMStorageContext()->DeleteLocalStorage(storage_origin);
+ callback.Run();
+ delete this;
}
-void StoragePartitionImpl::AsyncClearData(uint32 storage_mask) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+void StoragePartitionImpl::QuotaManagedDataDeletionHelper::ClearDataOnIOThread(
+ const scoped_refptr<quota::QuotaManager>& quota_manager,
+ const base::Time begin,
+ uint32 remove_mask,
+ uint32 quota_storage_remove_mask,
+ const GURL& remove_origin) {
+ std::set<GURL> origins;
+ if (!remove_origin.is_empty())
+ origins.insert(remove_origin);
+
+ IncrementTaskCountOnIO();
+ base::Closure decrement_callback = base::Bind(
+ &QuotaManagedDataDeletionHelper::DecrementTaskCountOnIO,
+ base::Unretained(this));
+
+ if (quota_storage_remove_mask & QUOTA_MANAGED_STORAGE_MASK_PERSISTENT) {
+ IncrementTaskCountOnIO();
+ if (origins.empty()) { // Remove for all origins.
+ // Ask the QuotaManager for all origins with temporary quota modified
+ // within the user-specified timeframe, and deal with the resulting set in
+ // ClearQuotaManagedOriginsOnIOThread().
+ quota_manager->GetOriginsModifiedSince(
+ quota::kStorageTypePersistent, begin,
+ base::Bind(&ClearQuotaManagedOriginsOnIOThread,
+ quota_manager, remove_mask, decrement_callback));
+ } else {
+ ClearQuotaManagedOriginsOnIOThread(
+ quota_manager, remove_mask, decrement_callback,
+ origins, quota::kStorageTypePersistent);
+ }
+ }
- // We ignore the media request context because it shares the same cookie store
- // as the main request context.
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::Bind(&ClearAllDataOnIOThread,
- storage_mask,
- url_request_context_,
- quota_manager_));
-
- if (storage_mask & kLocalDomStorage) {
- dom_storage_context_->GetLocalStorageUsage(
- base::Bind(&OnLocalStorageUsageInfo, dom_storage_context_));
+ // Do the same for temporary quota.
+ if (quota_storage_remove_mask & QUOTA_MANAGED_STORAGE_MASK_TEMPORARY) {
+ IncrementTaskCountOnIO();
+ if (origins.empty()) { // Remove for all origins.
+ quota_manager->GetOriginsModifiedSince(
+ quota::kStorageTypeTemporary, begin,
+ base::Bind(&ClearQuotaManagedOriginsOnIOThread,
+ quota_manager, remove_mask, decrement_callback));
+ } else {
+ ClearQuotaManagedOriginsOnIOThread(
+ quota_manager, remove_mask, decrement_callback,
+ origins, quota::kStorageTypeTemporary);
+ }
}
- if (storage_mask & kSessionDomStorage) {
- dom_storage_context_->GetSessionStorageUsage(
- base::Bind(&OnSessionStorageUsageInfo, dom_storage_context_));
+ // Do the same for syncable quota.
+ if (quota_storage_remove_mask & QUOTA_MANAGED_STORAGE_MASK_SYNCABLE) {
+ IncrementTaskCountOnIO();
+ if (origins.empty()) { // Remove for all origins.
+ quota_manager->GetOriginsModifiedSince(
+ quota::kStorageTypeSyncable, begin,
+ base::Bind(&ClearQuotaManagedOriginsOnIOThread,
+ quota_manager, remove_mask, decrement_callback));
+ } else {
+ ClearQuotaManagedOriginsOnIOThread(
+ quota_manager, remove_mask, decrement_callback,
+ origins, quota::kStorageTypeSyncable);
+ }
}
+
+ DecrementTaskCountOnIO();
}
-void StoragePartitionImpl::AsyncClearDataBetween(uint32 storage_mask,
- const base::Time& begin, const base::Time& end,
- const base::Closure& callback) {
+void StoragePartitionImpl::DataDeletionHelper::IncrementTaskCountOnUI() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- DCHECK(storage_mask == kShaderStorage);
+ ++task_count;
+}
- if (storage_mask & kShaderStorage) {
+void StoragePartitionImpl::DataDeletionHelper::DecrementTaskCountOnUI() {
+ if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&DataDeletionHelper::DecrementTaskCountOnUI,
+ base::Unretained(this)));
+ return;
+ }
+ DCHECK_GT(task_count, 0);
+ --task_count;
+ if (!task_count) {
+ callback.Run();
+ delete this;
+ }
+}
+
+void StoragePartitionImpl::DataDeletionHelper::ClearDataOnUIThread(
+ uint32 remove_mask,
+ uint32 quota_storage_remove_mask,
+ const GURL& remove_origin,
+ const base::FilePath& path,
+ net::URLRequestContextGetter* rq_context,
+ DOMStorageContextImpl* dom_storage_context,
+ quota::QuotaManager* quota_manager,
+ const base::Time begin,
+ const base::Time end) {
+ DCHECK_NE(remove_mask, 0u);
+ DCHECK(!callback.is_null());
+
+ IncrementTaskCountOnUI();
+ base::Closure decrement_callback = base::Bind(
+ &DataDeletionHelper::DecrementTaskCountOnUI, base::Unretained(this));
+
+ if (remove_mask & REMOVE_DATA_MASK_COOKIES) {
+ // Handle the cookies.
+ IncrementTaskCountOnUI();
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&ClearCookiesOnIOThread,
+ make_scoped_refptr(rq_context), begin, end,
+ decrement_callback));
+ }
+
+ if (remove_mask & REMOVE_DATA_MASK_INDEXEDDB ||
+ remove_mask & REMOVE_DATA_MASK_WEBSQL ||
+ remove_mask & REMOVE_DATA_MASK_APPCACHE ||
+ remove_mask & REMOVE_DATA_MASK_FILE_SYSTEMS) {
+ IncrementTaskCountOnUI();
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&ClearQuotaManagedDataOnIOThread,
+ make_scoped_refptr(quota_manager), begin,
+ remove_mask, quota_storage_remove_mask, remove_origin,
+ decrement_callback));
+ }
+
+ if (remove_mask & REMOVE_DATA_MASK_LOCAL_STORAGE) {
+ IncrementTaskCountOnUI();
+ ClearLocalStorageOnUIThread(
+ make_scoped_refptr(dom_storage_context),
+ remove_origin, begin, end, decrement_callback);
+
+ // ClearDataImpl cannot clear session storage data when a particular origin
+ // is specified. Therefore we ignore clearing session storage in this case.
+ // TODO(lazyboy): Fix.
+ if (remove_origin.is_empty()) {
+ IncrementTaskCountOnUI();
+ ClearSessionStorageOnUIThread(
+ make_scoped_refptr(dom_storage_context), decrement_callback);
+ }
+ }
+
+ if (remove_mask & REMOVE_DATA_MASK_SHADER_CACHE) {
+ IncrementTaskCountOnUI();
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
- base::Bind(&ClearShaderCacheOnIOThread, GetPath(), begin, end,
- callback));
+ base::Bind(&ClearShaderCacheOnIOThread,
+ path, begin, end, decrement_callback));
}
+
+ DecrementTaskCountOnUI();
+}
+
+
+void StoragePartitionImpl::ClearDataForOrigin(
+ uint32 remove_mask,
+ uint32 quota_storage_remove_mask,
+ const GURL& storage_origin,
+ net::URLRequestContextGetter* request_context_getter) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ ClearDataImpl(remove_mask, quota_storage_remove_mask, storage_origin,
+ request_context_getter, base::Time(), base::Time::Max(),
+ base::Bind(&base::DoNothing));
+}
+
+void StoragePartitionImpl::ClearDataForUnboundedRange(
+ uint32 remove_mask,
+ uint32 quota_storage_remove_mask) {
+ ClearDataImpl(remove_mask, quota_storage_remove_mask, GURL(),
+ GetURLRequestContext(), base::Time(), base::Time::Max(),
+ base::Bind(&base::DoNothing));
+}
+
+void StoragePartitionImpl::ClearDataForRange(uint32 remove_mask,
+ uint32 quota_storage_remove_mask,
+ const base::Time& begin,
+ const base::Time& end,
+ const base::Closure& callback) {
+ ClearDataImpl(remove_mask, quota_storage_remove_mask, GURL(),
+ GetURLRequestContext(), begin, end, callback);
}
WebRTCIdentityStore* StoragePartitionImpl::GetWebRTCIdentityStore() {
diff --git a/content/browser/storage_partition_impl.h b/content/browser/storage_partition_impl.h
index 9dcdfeced5..0410f4d909 100644
--- a/content/browser/storage_partition_impl.h
+++ b/content/browser/storage_partition_impl.h
@@ -31,19 +31,26 @@ class StoragePartitionImpl : public StoragePartition {
virtual webkit_database::DatabaseTracker* GetDatabaseTracker() OVERRIDE;
virtual DOMStorageContextImpl* GetDOMStorageContext() OVERRIDE;
virtual IndexedDBContextImpl* GetIndexedDBContext() OVERRIDE;
- virtual void AsyncClearDataForOrigin(
- uint32 storage_mask,
+
+ virtual void ClearDataForOrigin(
+ uint32 remove_mask,
+ uint32 quota_storage_remove_mask,
const GURL& storage_origin,
net::URLRequestContextGetter* request_context_getter) OVERRIDE;
- virtual void AsyncClearData(uint32 storage_mask) OVERRIDE;
- virtual void AsyncClearDataBetween(
- uint32 storage_mask,
- const base::Time& begin,
- const base::Time& end,
- const base::Closure& callback) OVERRIDE;
+ virtual void ClearDataForUnboundedRange(
+ uint32 remove_mask,
+ uint32 quota_storage_remove_mask) OVERRIDE;
+ virtual void ClearDataForRange(uint32 remove_mask,
+ uint32 quota_storage_remove_mask,
+ const base::Time& begin,
+ const base::Time& end,
+ const base::Closure& callback) OVERRIDE;
WebRTCIdentityStore* GetWebRTCIdentityStore();
+ struct DataDeletionHelper;
+ struct QuotaManagedDataDeletionHelper;
+
private:
friend class StoragePartitionImplMap;
FRIEND_TEST_ALL_PREFIXES(StoragePartitionShaderClearTest, ClearShaderCache);
@@ -58,6 +65,10 @@ class StoragePartitionImpl : public StoragePartition {
bool in_memory,
const base::FilePath& profile_path);
+ // Quota managed data uses a different bitmask for types than
+ // StoragePartition uses. This method generates that mask.
+ static int GenerateQuotaClientMask(uint32 remove_mask);
+
CONTENT_EXPORT StoragePartitionImpl(
const base::FilePath& partition_path,
quota::QuotaManager* quota_manager,
@@ -68,6 +79,14 @@ class StoragePartitionImpl : public StoragePartition {
IndexedDBContextImpl* indexed_db_context,
scoped_ptr<WebRTCIdentityStore> webrtc_identity_store);
+ void ClearDataImpl(uint32 remove_mask,
+ uint32 quota_storage_remove_mask,
+ const GURL& remove_origin,
+ net::URLRequestContextGetter* rq_context,
+ const base::Time begin,
+ const base::Time end,
+ const base::Closure& callback);
+
// Used by StoragePartitionImplMap.
//
// TODO(ajwong): These should be taken in the constructor and in Create() but
diff --git a/content/browser/storage_partition_impl_map.cc b/content/browser/storage_partition_impl_map.cc
index 8b6556eec1..c5721aee66 100644
--- a/content/browser/storage_partition_impl_map.cc
+++ b/content/browser/storage_partition_impl_map.cc
@@ -496,7 +496,11 @@ void StoragePartitionImplMap::AsyncObliterate(
++it) {
const StoragePartitionConfig& config = it->first;
if (config.partition_domain == partition_domain) {
- it->second->AsyncClearData(StoragePartition::kAllStorage);
+ it->second->ClearDataForUnboundedRange(
+ // All except shader cache.
+ StoragePartition::REMOVE_DATA_MASK_ALL &
+ (~StoragePartition::REMOVE_DATA_MASK_SHADER_CACHE),
+ StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL);
if (!config.in_memory) {
paths_to_keep.push_back(it->second->GetPath());
}
diff --git a/content/browser/storage_partition_impl_unittest.cc b/content/browser/storage_partition_impl_unittest.cc
index 36af6387a6..22078374f5 100644
--- a/content/browser/storage_partition_impl_unittest.cc
+++ b/content/browser/storage_partition_impl_unittest.cc
@@ -98,8 +98,10 @@ class StoragePartitionShaderClearTest : public testing::Test {
void ClearData(content::StoragePartitionImpl* sp,
const base::Closure& cb) {
base::Time time;
- sp->AsyncClearDataBetween(content::StoragePartition::kShaderStorage,
- time, time, cb);
+ sp->ClearDataForRange(
+ StoragePartition::REMOVE_DATA_MASK_SHADER_CACHE,
+ StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL,
+ time, time, cb);
}
TEST_F(StoragePartitionShaderClearTest, ClearShaderCache) {
diff --git a/content/browser/streams/stream.cc b/content/browser/streams/stream.cc
index 38f91b82e5..f1fa1043e7 100644
--- a/content/browser/streams/stream.cc
+++ b/content/browser/streams/stream.cc
@@ -72,7 +72,7 @@ void Stream::AddData(scoped_refptr<net::IOBuffer> buffer, size_t size) {
}
void Stream::Finalize() {
- writer_->Close(DOWNLOAD_INTERRUPT_REASON_NONE);
+ writer_->Close(0);
writer_.reset(NULL);
// Continue asynchronously.
diff --git a/content/browser/web_contents/render_view_host_manager.cc b/content/browser/web_contents/render_view_host_manager.cc
index 0c8d26f1b2..9d29a09c6a 100644
--- a/content/browser/web_contents/render_view_host_manager.cc
+++ b/content/browser/web_contents/render_view_host_manager.cc
@@ -490,14 +490,10 @@ SiteInstance* RenderViewHostManager::GetSiteInstanceForEntry(
SiteInstance* curr_instance) {
// NOTE: This is only called when ShouldTransitionCrossSite is true.
+ const GURL& dest_url = entry.GetURL();
NavigationControllerImpl& controller =
delegate_->GetControllerForRenderManager();
BrowserContext* browser_context = controller.GetBrowserContext();
- const GURL& dest_url = GetContentClient()->browser()->
- GetPossiblyPrivilegedURL(browser_context,
- entry.GetURL(),
- entry.is_renderer_initiated(),
- curr_instance);
// If the entry has an instance already we should use it.
if (entry.site_instance())
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index fe34bc0ef8..e9f0a1fbe5 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -9,6 +9,7 @@
#include "base/command_line.h"
#include "base/debug/trace_event.h"
#include "base/lazy_instance.h"
+#include "base/logging.h"
#include "base/metrics/histogram.h"
#include "base/metrics/stats_counters.h"
#include "base/strings/string16.h"
@@ -81,6 +82,7 @@
#include "net/url_request/url_request_context_getter.h"
#include "ui/base/layout.h"
#include "ui/base/touch/touch_device.h"
+#include "ui/base/touch/touch_enabled.h"
#include "ui/base/ui_base_switches.h"
#include "ui/gfx/display.h"
#include "ui/gfx/screen.h"
@@ -266,7 +268,8 @@ void MakeNavigateParams(const NavigationEntryImpl& entry,
} // namespace
WebContents* WebContents::Create(const WebContents::CreateParams& params) {
- return WebContentsImpl::CreateWithOpener(params, NULL);
+ return WebContentsImpl::CreateWithOpener(
+ params, static_cast<WebContentsImpl*>(params.opener));
}
WebContents* WebContents::CreateWithSessionStorage(
@@ -375,7 +378,7 @@ WebContentsImpl::~WebContentsImpl() {
// Clear out any JavaScript state.
if (dialog_manager_)
- dialog_manager_->ResetJavaScriptState(this);
+ dialog_manager_->WebContentsDestroyed(this);
if (color_chooser_)
color_chooser_->End();
@@ -477,11 +480,7 @@ WebPreferences WebContentsImpl::GetWebkitPrefs(RenderViewHost* rvh,
prefs.experimental_webgl_enabled =
GpuProcessHost::gpu_enabled() &&
!command_line.HasSwitch(switches::kDisable3DAPIs) &&
-#if defined(OS_ANDROID)
- command_line.HasSwitch(switches::kEnableExperimentalWebGL);
-#else
!command_line.HasSwitch(switches::kDisableExperimentalWebGL);
-#endif
prefs.flash_3d_enabled =
GpuProcessHost::gpu_enabled() &&
@@ -559,23 +558,9 @@ WebPreferences WebContentsImpl::GetWebkitPrefs(RenderViewHost* rvh,
switches::kDisableGestureRequirementForMediaPlayback);
#endif
- bool touch_device_present = false;
- touch_device_present = ui::IsTouchDevicePresent();
- const std::string touch_enabled_switch =
- command_line.HasSwitch(switches::kTouchEvents) ?
- command_line.GetSwitchValueASCII(switches::kTouchEvents) :
- switches::kTouchEventsAuto;
-
- if (touch_enabled_switch.empty() ||
- touch_enabled_switch == switches::kTouchEventsEnabled) {
- prefs.touch_enabled = true;
- } else if (touch_enabled_switch == switches::kTouchEventsAuto) {
- prefs.touch_enabled = touch_device_present;
- } else if (touch_enabled_switch != switches::kTouchEventsDisabled) {
- LOG(ERROR) << "Invalid --touch-events option: " << touch_enabled_switch;
- }
-
- prefs.device_supports_touch = prefs.touch_enabled && touch_device_present;
+ prefs.touch_enabled = ui::AreTouchEventsEnabled();
+ prefs.device_supports_touch = prefs.touch_enabled &&
+ ui::IsTouchDevicePresent();
#if defined(OS_ANDROID)
prefs.device_supports_mouse = false;
#endif
@@ -2701,6 +2686,8 @@ void WebContentsImpl::DidNavigateMainFramePostCommit(
// Once the main frame is navigated, we're no longer considered to have
// displayed insecure content.
displayed_insecure_content_ = false;
+ SSLManager::NotifySSLInternalStateChanged(
+ GetController().GetBrowserContext());
}
// Notify observers about navigation.
@@ -2712,13 +2699,9 @@ void WebContentsImpl::DidNavigateAnyFramePostCommit(
RenderViewHost* render_view_host,
const LoadCommittedDetails& details,
const ViewHostMsg_FrameNavigate_Params& params) {
- // If we navigate off the page, reset JavaScript state. This does nothing
- // to prevent a malicious script from spamming messages, since the script
- // could just reload the page to stop blocking.
- if (dialog_manager_ && !details.is_in_page) {
- dialog_manager_->ResetJavaScriptState(this);
- dialog_manager_ = NULL;
- }
+ // If we navigate off the page, close all JavaScript dialogs.
+ if (dialog_manager_ && !details.is_in_page)
+ dialog_manager_->CancelActiveAndPendingDialogs(this);
// Notify observers about navigation.
FOR_EACH_OBSERVER(WebContentsObserver, observers_,
diff --git a/content/browser/webui/shared_resources_data_source.cc b/content/browser/webui/shared_resources_data_source.cc
index 23cdc3d23a..42d0d119cb 100644
--- a/content/browser/webui/shared_resources_data_source.cc
+++ b/content/browser/webui/shared_resources_data_source.cc
@@ -6,6 +6,7 @@
#include "base/logging.h"
#include "base/memory/ref_counted_memory.h"
+#include "base/strings/string_util.h"
#include "base/threading/thread_restrictions.h"
#include "content/public/common/content_client.h"
#include "content/public/common/url_constants.h"
@@ -14,10 +15,37 @@
namespace {
+const char kAppImagesPath[] = "images/apps/";
+const char kAppImagesPath2x[] = "images/2x/apps/";
+
+const char kReplacement[] = "../../resources/default_100_percent/common/";
+const char kReplacement2x[] = "../../resources/default_200_percent/common/";
+
+// This entire method is a hack introduced to be able to handle apps images
+// that exist in the ui/resources directory. From JS/CSS, we still load the
+// image as if it were chrome://resources/images/apps/myappimage.png, if that
+// path doesn't exist, we check to see if it that image exists in the relative
+// path to ui/resources instead.
+// TODO(rkc): Once we have a separate source for apps, remove this code.
+bool AppsRelativePathMatch(const std::string& path,
+ const std::string& compareto) {
+ if (StartsWithASCII(path, kAppImagesPath, false)) {
+ if (compareto ==
+ (kReplacement + path.substr(arraysize(kAppImagesPath) - 1)))
+ return true;
+ } else if (StartsWithASCII(path, kAppImagesPath2x, false)) {
+ if (compareto ==
+ (kReplacement2x + path.substr(arraysize(kAppImagesPath) - 1)))
+ return true;
+ }
+ return false;
+}
+
int PathToIDR(const std::string& path) {
int idr = -1;
for (size_t i = 0; i < kWebuiResourcesSize; ++i) {
- if (kWebuiResources[i].name == path) {
+ if ((path == kWebuiResources[i].name) ||
+ AppsRelativePathMatch(path, kWebuiResources[i].name)) {
idr = kWebuiResources[i].value;
break;
}