summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
authorjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-16 22:30:19 +0000
committerjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-16 22:30:19 +0000
commit230b7efa5edf3fe5964b55ea0aa801563996d4fc (patch)
tree4ee6e0ffbbb5ca3bc5699e3adefa390279c6f357 /content
parenteb7d6dd92533eae8c2514735750ccd8d0e9c5875 (diff)
downloadchromium_src-230b7efa5edf3fe5964b55ea0aa801563996d4fc.zip
chromium_src-230b7efa5edf3fe5964b55ea0aa801563996d4fc.tar.gz
chromium_src-230b7efa5edf3fe5964b55ea0aa801563996d4fc.tar.bz2
Move a bunch of html5 renderer code to content.
TBR=avi Review URL: http://codereview.chromium.org/6703003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@78449 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r--content/content_renderer.gypi16
-rw-r--r--content/renderer/audio_device.cc188
-rw-r--r--content/renderer/audio_device.h84
-rw-r--r--content/renderer/audio_message_filter.cc147
-rw-r--r--content/renderer/audio_message_filter.h121
-rw-r--r--content/renderer/audio_message_filter_unittest.cc200
-rw-r--r--content/renderer/cookie_message_filter.cc19
-rw-r--r--content/renderer/cookie_message_filter.h30
-rw-r--r--content/renderer/device_orientation_dispatcher.cc91
-rw-r--r--content/renderer/device_orientation_dispatcher.h42
-rw-r--r--content/renderer/geolocation_dispatcher.cc149
-rw-r--r--content/renderer/geolocation_dispatcher.h66
-rw-r--r--content/renderer/indexed_db_dispatcher.cc455
-rw-r--r--content/renderer/indexed_db_dispatcher.h176
-rw-r--r--content/renderer/media/audio_renderer_impl.cc1
-rw-r--r--content/renderer/media/audio_renderer_impl.h2
-rw-r--r--content/renderer/notification_provider.cc188
-rw-r--r--content/renderer/notification_provider.h58
-rw-r--r--content/renderer/speech_input_dispatcher.cc95
-rw-r--r--content/renderer/speech_input_dispatcher.h51
20 files changed, 2177 insertions, 2 deletions
diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi
index dfd5246..cfed384 100644
--- a/content/content_renderer.gypi
+++ b/content/content_renderer.gypi
@@ -18,14 +18,28 @@
'..',
],
'sources': [
+ 'renderer/audio_device.cc',
+ 'renderer/audio_device.h',
+ 'renderer/audio_message_filter.cc',
+ 'renderer/audio_message_filter.h',
+ 'renderer/cookie_message_filter.cc',
+ 'renderer/cookie_message_filter.h',
+ 'renderer/device_orientation_dispatcher.cc',
+ 'renderer/device_orientation_dispatcher.h',
+ 'renderer/geolocation_dispatcher.cc',
+ 'renderer/geolocation_dispatcher.h',
'renderer/ggl.cc',
'renderer/ggl.h',
+ 'renderer/indexed_db_dispatcher.cc',
+ 'renderer/indexed_db_dispatcher.h',
'renderer/media/audio_renderer_impl.cc',
'renderer/media/audio_renderer_impl.h',
'renderer/media/gles2_video_decode_context.cc',
'renderer/media/gles2_video_decode_context.h',
'renderer/media/ipc_video_decoder.cc',
'renderer/media/ipc_video_decoder.h',
+ 'renderer/notification_provider.cc',
+ 'renderer/notification_provider.h',
'renderer/p2p/ipc_network_manager.cc',
'renderer/p2p/ipc_network_manager.h',
'renderer/p2p/ipc_socket_factory.cc',
@@ -34,6 +48,8 @@
'renderer/p2p/socket_client.h',
'renderer/p2p/socket_dispatcher.cc',
'renderer/p2p/socket_dispatcher.h',
+ 'renderer/speech_input_dispatcher.cc',
+ 'renderer/speech_input_dispatcher.h',
],
},
],
diff --git a/content/renderer/audio_device.cc b/content/renderer/audio_device.cc
new file mode 100644
index 0000000..cf1dd7d
--- /dev/null
+++ b/content/renderer/audio_device.cc
@@ -0,0 +1,188 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/audio_device.h"
+
+#include "base/singleton.h"
+#include "chrome/common/render_messages.h"
+#include "chrome/common/render_messages_params.h"
+#include "chrome/renderer/render_thread.h"
+#include "media/audio/audio_util.h"
+
+scoped_refptr<AudioMessageFilter> AudioDevice::filter_;
+
+namespace {
+
+// AudioMessageFilterCreator is intended to be used as a singleton so we can
+// get access to a shared AudioMessageFilter.
+// Example usage:
+// AudioMessageFilter* filter = AudioMessageFilterCreator::SharedFilter();
+
+class AudioMessageFilterCreator {
+ public:
+ AudioMessageFilterCreator() {
+ int routing_id;
+ RenderThread::current()->Send(
+ new ViewHostMsg_GenerateRoutingID(&routing_id));
+ filter_ = new AudioMessageFilter(routing_id);
+ RenderThread::current()->AddFilter(filter_);
+ }
+
+ static AudioMessageFilter* SharedFilter() {
+ return GetInstance()->filter_.get();
+ }
+
+ static AudioMessageFilterCreator* GetInstance() {
+ return Singleton<AudioMessageFilterCreator>::get();
+ }
+
+ private:
+ scoped_refptr<AudioMessageFilter> filter_;
+};
+
+}
+
+AudioDevice::AudioDevice(size_t buffer_size,
+ int channels,
+ double sample_rate,
+ RenderCallback* callback)
+ : buffer_size_(buffer_size),
+ channels_(channels),
+ sample_rate_(sample_rate),
+ callback_(callback),
+ stream_id_(0) {
+ audio_data_.reserve(channels);
+ for (int i = 0; i < channels; ++i) {
+ float* channel_data = new float[buffer_size];
+ audio_data_.push_back(channel_data);
+ }
+}
+
+AudioDevice::~AudioDevice() {
+ Stop();
+ for (int i = 0; i < channels_; ++i)
+ delete [] audio_data_[i];
+}
+
+bool AudioDevice::Start() {
+ // Make sure we don't call Start() more than once.
+ DCHECK_EQ(0, stream_id_);
+ if (stream_id_)
+ return false;
+
+ // Lazily create the message filter and share across AudioDevice instances.
+ filter_ = AudioMessageFilterCreator::SharedFilter();
+
+ stream_id_ = filter_->AddDelegate(this);
+
+ ViewHostMsg_Audio_CreateStream_Params params;
+ params.params.format = AudioParameters::AUDIO_PCM_LOW_LATENCY;
+ params.params.channels = channels_;
+ params.params.sample_rate = static_cast<int>(sample_rate_);
+ params.params.bits_per_sample = 16;
+ params.params.samples_per_packet = buffer_size_;
+
+ filter_->Send(
+ new ViewHostMsg_CreateAudioStream(0, stream_id_, params, true));
+
+ return true;
+}
+
+bool AudioDevice::Stop() {
+ if (stream_id_) {
+ OnDestroy();
+ return true;
+ }
+ return false;
+}
+
+void AudioDevice::OnDestroy() {
+ // Make sure we don't call destroy more than once.
+ DCHECK_NE(0, stream_id_);
+ if (!stream_id_)
+ return;
+
+ filter_->RemoveDelegate(stream_id_);
+ filter_->Send(new ViewHostMsg_CloseAudioStream(0, stream_id_));
+ stream_id_ = 0;
+ if (audio_thread_.get()) {
+ socket_->Close();
+ audio_thread_->Join();
+ }
+}
+
+void AudioDevice::OnRequestPacket(AudioBuffersState buffers_state) {
+ // This method does not apply to the low-latency system.
+ NOTIMPLEMENTED();
+}
+
+void AudioDevice::OnStateChanged(
+ const ViewMsg_AudioStreamState_Params& state) {
+ // Not needed in this simple implementation.
+ NOTIMPLEMENTED();
+}
+
+void AudioDevice::OnCreated(
+ base::SharedMemoryHandle handle, uint32 length) {
+ // Not needed in this simple implementation.
+ NOTIMPLEMENTED();
+}
+
+void AudioDevice::OnLowLatencyCreated(
+ base::SharedMemoryHandle handle,
+ base::SyncSocket::Handle socket_handle,
+ uint32 length) {
+
+#if defined(OS_WIN)
+ DCHECK(handle);
+ DCHECK(socket_handle);
+#else
+ DCHECK_GE(handle.fd, 0);
+ DCHECK_GE(socket_handle, 0);
+#endif
+ DCHECK(length);
+ DCHECK(!audio_thread_.get());
+
+ // TODO(crogers) : check that length is big enough for buffer_size_
+
+ shared_memory_.reset(new base::SharedMemory(handle, false));
+ shared_memory_->Map(length);
+
+ socket_.reset(new base::SyncSocket(socket_handle));
+ // Allow the client to pre-populate the buffer.
+ FireRenderCallback();
+
+ // TODO(crogers): we could optionally set the thread to high-priority
+ audio_thread_.reset(
+ new base::DelegateSimpleThread(this, "renderer_audio_thread"));
+ audio_thread_->Start();
+
+ filter_->Send(new ViewHostMsg_PlayAudioStream(0, stream_id_));
+}
+
+void AudioDevice::OnVolume(double volume) {
+ // Not needed in this simple implementation.
+ NOTIMPLEMENTED();
+}
+
+// Our audio thread runs here.
+void AudioDevice::Run() {
+ int pending_data;
+ while (sizeof(pending_data) == socket_->Receive(&pending_data,
+ sizeof(pending_data)) &&
+ pending_data >= 0) {
+ FireRenderCallback();
+ }
+}
+
+void AudioDevice::FireRenderCallback() {
+ if (callback_) {
+ // Ask client to render audio.
+ callback_->Render(audio_data_, buffer_size_);
+
+ // Interleave, scale, and clip to int16.
+ int16* output_buffer16 = static_cast<int16*>(shared_memory_data());
+ media::InterleaveFloatToInt16(audio_data_, output_buffer16, buffer_size_);
+ }
+}
diff --git a/content/renderer/audio_device.h b/content/renderer/audio_device.h
new file mode 100644
index 0000000..9f152bf
--- /dev/null
+++ b/content/renderer/audio_device.h
@@ -0,0 +1,84 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_AUDIO_DEVICE_H_
+#define CONTENT_RENDERER_AUDIO_DEVICE_H_
+#pragma once
+
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/scoped_ptr.h"
+#include "base/shared_memory.h"
+#include "base/threading/simple_thread.h"
+#include "content/renderer/audio_message_filter.h"
+
+// Each instance of AudioDevice corresponds to one host stream.
+// This class is not thread-safe, so its methods must be called from
+// the same thread.
+class AudioDevice : public AudioMessageFilter::Delegate,
+ public base::DelegateSimpleThread::Delegate {
+ public:
+ class RenderCallback {
+ public:
+ virtual void Render(const std::vector<float*>& audio_data,
+ size_t number_of_frames) = 0;
+ protected:
+ virtual ~RenderCallback() {}
+ };
+
+ // |buffer_size| is the number of sample-frames.
+ AudioDevice(size_t buffer_size,
+ int channels,
+ double sample_rate,
+ RenderCallback* callback);
+ virtual ~AudioDevice();
+
+ // Returns |true| on success.
+ bool Start();
+ bool Stop();
+
+ private:
+ // AudioMessageFilter::Delegate implementation.
+ virtual void OnRequestPacket(AudioBuffersState buffers_state);
+ virtual void OnStateChanged(const ViewMsg_AudioStreamState_Params& state);
+ virtual void OnCreated(base::SharedMemoryHandle handle, uint32 length);
+ virtual void OnLowLatencyCreated(base::SharedMemoryHandle handle,
+ base::SyncSocket::Handle socket_handle,
+ uint32 length);
+ virtual void OnVolume(double volume);
+ virtual void OnDestroy();
+
+ // DelegateSimpleThread::Delegate implementation.
+ virtual void Run();
+
+ // Format
+ size_t buffer_size_; // in sample-frames
+ int channels_;
+ double sample_rate_;
+
+ // Calls the client's callback for rendering audio.
+ void FireRenderCallback();
+ RenderCallback* callback_;
+
+ // The client callback renders audio into here.
+ std::vector<float*> audio_data_;
+
+ // Callbacks for rendering audio occur on this thread.
+ scoped_ptr<base::DelegateSimpleThread> audio_thread_;
+
+ // IPC message stuff.
+ base::SharedMemory* shared_memory() { return shared_memory_.get(); }
+ base::SyncSocket* socket() { return socket_.get(); }
+ void* shared_memory_data() { return shared_memory()->memory(); }
+
+ static scoped_refptr<AudioMessageFilter> filter_;
+ int32 stream_id_;
+ scoped_ptr<base::SharedMemory> shared_memory_;
+ scoped_ptr<base::SyncSocket> socket_;
+
+ DISALLOW_COPY_AND_ASSIGN(AudioDevice);
+};
+
+#endif // CONTENT_RENDERER_AUDIO_DEVICE_H_
diff --git a/content/renderer/audio_message_filter.cc b/content/renderer/audio_message_filter.cc
new file mode 100644
index 0000000..317943c
--- /dev/null
+++ b/content/renderer/audio_message_filter.cc
@@ -0,0 +1,147 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/audio_message_filter.h"
+
+#include "base/message_loop.h"
+#include "base/time.h"
+#include "chrome/common/render_messages.h"
+#include "chrome/common/render_messages_params.h"
+#include "ipc/ipc_logging.h"
+
+AudioMessageFilter::AudioMessageFilter(int32 route_id)
+ : channel_(NULL),
+ route_id_(route_id),
+ message_loop_(NULL) {
+}
+
+AudioMessageFilter::~AudioMessageFilter() {
+}
+
+// Called on the IPC thread.
+bool AudioMessageFilter::Send(IPC::Message* message) {
+ if (!channel_) {
+ delete message;
+ return false;
+ }
+
+ if (MessageLoop::current() != message_loop_) {
+ // Can only access the IPC::Channel on the IPC thread since it's not thread
+ // safe.
+ message_loop_->PostTask(
+ FROM_HERE, NewRunnableMethod(this, &AudioMessageFilter::Send, message));
+ return true;
+ }
+
+ message->set_routing_id(route_id_);
+ return channel_->Send(message);
+}
+
+bool AudioMessageFilter::OnMessageReceived(const IPC::Message& message) {
+ if (message.routing_id() != route_id_)
+ return false;
+
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(AudioMessageFilter, message)
+ IPC_MESSAGE_HANDLER(ViewMsg_RequestAudioPacket, OnRequestPacket)
+ IPC_MESSAGE_HANDLER(ViewMsg_NotifyAudioStreamCreated, OnStreamCreated)
+ IPC_MESSAGE_HANDLER(ViewMsg_NotifyLowLatencyAudioStreamCreated,
+ OnLowLatencyStreamCreated)
+ IPC_MESSAGE_HANDLER(ViewMsg_NotifyAudioStreamStateChanged,
+ OnStreamStateChanged)
+ IPC_MESSAGE_HANDLER(ViewMsg_NotifyAudioStreamVolume, OnStreamVolume)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+void AudioMessageFilter::OnFilterAdded(IPC::Channel* channel) {
+ // Captures the message loop for IPC.
+ message_loop_ = MessageLoop::current();
+ channel_ = channel;
+}
+
+void AudioMessageFilter::OnFilterRemoved() {
+ channel_ = NULL;
+}
+
+void AudioMessageFilter::OnChannelClosing() {
+ channel_ = NULL;
+}
+
+void AudioMessageFilter::OnRequestPacket(const IPC::Message& msg,
+ int stream_id,
+ AudioBuffersState buffers_state) {
+ Delegate* delegate = delegates_.Lookup(stream_id);
+ if (!delegate) {
+ DLOG(WARNING) << "Got audio packet request for a non-existent or removed"
+ " audio renderer.";
+ return;
+ }
+
+ delegate->OnRequestPacket(buffers_state);
+}
+
+void AudioMessageFilter::OnStreamCreated(int stream_id,
+ base::SharedMemoryHandle handle,
+ uint32 length) {
+ Delegate* delegate = delegates_.Lookup(stream_id);
+ if (!delegate) {
+ DLOG(WARNING) << "Got audio stream event for a non-existent or removed"
+ " audio renderer.";
+ return;
+ }
+ delegate->OnCreated(handle, length);
+}
+
+void AudioMessageFilter::OnLowLatencyStreamCreated(
+ int stream_id,
+ base::SharedMemoryHandle handle,
+#if defined(OS_WIN)
+ base::SyncSocket::Handle socket_handle,
+#else
+ base::FileDescriptor socket_descriptor,
+#endif
+ uint32 length) {
+ Delegate* delegate = delegates_.Lookup(stream_id);
+ if (!delegate) {
+ DLOG(WARNING) << "Got audio stream event for a non-existent or removed"
+ " audio renderer.";
+ return;
+ }
+#if !defined(OS_WIN)
+ base::SyncSocket::Handle socket_handle = socket_descriptor.fd;
+#endif
+ delegate->OnLowLatencyCreated(handle, socket_handle, length);
+}
+
+void AudioMessageFilter::OnStreamStateChanged(
+ int stream_id,
+ const ViewMsg_AudioStreamState_Params& state) {
+ Delegate* delegate = delegates_.Lookup(stream_id);
+ if (!delegate) {
+ DLOG(WARNING) << "Got audio stream event for a non-existent or removed"
+ " audio renderer.";
+ return;
+ }
+ delegate->OnStateChanged(state);
+}
+
+void AudioMessageFilter::OnStreamVolume(int stream_id, double volume) {
+ Delegate* delegate = delegates_.Lookup(stream_id);
+ if (!delegate) {
+ DLOG(WARNING) << "Got audio stream event for a non-existent or removed"
+ " audio renderer.";
+ return;
+ }
+ delegate->OnVolume(volume);
+}
+
+int32 AudioMessageFilter::AddDelegate(Delegate* delegate) {
+ return delegates_.Add(delegate);
+}
+
+void AudioMessageFilter::RemoveDelegate(int32 id) {
+ delegates_.Remove(id);
+}
diff --git a/content/renderer/audio_message_filter.h b/content/renderer/audio_message_filter.h
new file mode 100644
index 0000000..e362839
--- /dev/null
+++ b/content/renderer/audio_message_filter.h
@@ -0,0 +1,121 @@
+// Copyright (c) 2010 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.
+//
+// MessageFilter that handles audio messages and delegates them to audio
+// renderers. Created on render thread, AudioMessageFilter is operated on
+// IO thread (main thread of render process), it intercepts audio messages
+// and process them on IO thread since these messages are time critical.
+
+#ifndef CONTENT_RENDERER_AUDIO_MESSAGE_FILTER_H_
+#define CONTENT_RENDERER_AUDIO_MESSAGE_FILTER_H_
+#pragma once
+
+#include "base/gtest_prod_util.h"
+#include "base/id_map.h"
+#include "base/shared_memory.h"
+#include "base/sync_socket.h"
+#include "ipc/ipc_channel_proxy.h"
+#include "media/audio/audio_buffers_state.h"
+
+struct ViewMsg_AudioStreamState_Params;
+
+namespace base {
+class Time;
+}
+
+class AudioMessageFilter : public IPC::ChannelProxy::MessageFilter {
+ public:
+ class Delegate {
+ public:
+ // Called when an audio packet is requested from the browser process.
+ virtual void OnRequestPacket(AudioBuffersState buffers_state) = 0;
+
+ // Called when state of an audio stream has changed in the browser process.
+ virtual void OnStateChanged(
+ const ViewMsg_AudioStreamState_Params& state) = 0;
+
+ // Called when an audio stream has been created in the browser process.
+ virtual void OnCreated(base::SharedMemoryHandle handle, uint32 length) = 0;
+
+ // Called when a low-latency audio stream has been created in the browser
+ // process.
+ virtual void OnLowLatencyCreated(base::SharedMemoryHandle handle,
+ base::SyncSocket::Handle socket_handle,
+ uint32 length) = 0;
+
+ // Called when notification of stream volume is received from the browser
+ // process.
+ virtual void OnVolume(double volume) = 0;
+
+ protected:
+ virtual ~Delegate() {}
+ };
+
+ explicit AudioMessageFilter(int32 route_id);
+ ~AudioMessageFilter();
+
+ // Add a delegate to the map and return id of the entry.
+ int32 AddDelegate(Delegate* delegate);
+
+ // Remove a delegate referenced by |id| from the map.
+ void RemoveDelegate(int32 id);
+
+ // Sends an IPC message using |channel_|.
+ bool Send(IPC::Message* message);
+
+ MessageLoop* message_loop() { return message_loop_; }
+
+ private:
+ // For access to |message_loop_|.
+ friend class AudioRendererImplTest;
+
+ FRIEND_TEST_ALL_PREFIXES(AudioMessageFilterTest, Basic);
+ FRIEND_TEST_ALL_PREFIXES(AudioMessageFilterTest, Delegates);
+
+ // IPC::ChannelProxy::MessageFilter override. Called on IO thread.
+ virtual bool OnMessageReceived(const IPC::Message& message);
+ virtual void OnFilterAdded(IPC::Channel* channel);
+ virtual void OnFilterRemoved();
+ virtual void OnChannelClosing();
+
+ // Received when browser process wants more audio packet.
+ void OnRequestPacket(const IPC::Message& msg, int stream_id,
+ AudioBuffersState buffers_state);
+
+ // Received when browser process has created an audio output stream.
+ void OnStreamCreated(int stream_id, base::SharedMemoryHandle handle,
+ uint32 length);
+
+ // Received when browser process has created an audio output stream of low
+ // latency.
+ void OnLowLatencyStreamCreated(int stream_id, base::SharedMemoryHandle handle,
+#if defined(OS_WIN)
+ base::SyncSocket::Handle socket_handle,
+#else
+ base::FileDescriptor socket_descriptor,
+#endif
+ uint32 length);
+
+
+ // Received when internal state of browser process' audio output device has
+ // changed.
+ void OnStreamStateChanged(int stream_id,
+ const ViewMsg_AudioStreamState_Params& state);
+
+ // Notification of volume property of an audio output stream.
+ void OnStreamVolume(int stream_id, double volume);
+
+ // A map of stream ids to delegates.
+ IDMap<Delegate> delegates_;
+
+ IPC::Channel* channel_;
+
+ int32 route_id_;
+
+ MessageLoop* message_loop_;
+
+ DISALLOW_COPY_AND_ASSIGN(AudioMessageFilter);
+};
+
+#endif // CONTENT_RENDERER_AUDIO_MESSAGE_FILTER_H_
diff --git a/content/renderer/audio_message_filter_unittest.cc b/content/renderer/audio_message_filter_unittest.cc
new file mode 100644
index 0000000..bfd42eb
--- /dev/null
+++ b/content/renderer/audio_message_filter_unittest.cc
@@ -0,0 +1,200 @@
+// Copyright (c) 2010 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/message_loop.h"
+#include "chrome/common/render_messages.h"
+#include "chrome/common/render_messages_params.h"
+#include "content/renderer/audio_message_filter.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+class MockAudioDelegate : public AudioMessageFilter::Delegate {
+ public:
+ MockAudioDelegate() {
+ Reset();
+ }
+
+ virtual void OnRequestPacket(AudioBuffersState buffers_state) {
+ request_packet_received_ = true;
+ buffers_state_ = buffers_state;
+ }
+
+ virtual void OnStateChanged(const ViewMsg_AudioStreamState_Params& state) {
+ state_changed_received_ = true;
+ state_ = state;
+ }
+
+ virtual void OnCreated(base::SharedMemoryHandle handle, uint32 length) {
+ created_received_ = true;
+ handle_ = handle;
+ length_ = length;
+ }
+
+ virtual void OnLowLatencyCreated(base::SharedMemoryHandle handle,
+ base::SyncSocket::Handle,
+ uint32 length) {
+ }
+
+ virtual void OnVolume(double volume) {
+ volume_received_ = true;
+ volume_ = volume;
+ }
+
+ void Reset() {
+ request_packet_received_ = false;
+ buffers_state_ = AudioBuffersState();
+ buffers_state_.timestamp = base::Time();
+
+ state_changed_received_ = false;
+ state_.state = ViewMsg_AudioStreamState_Params::kError;
+
+ created_received_ = false;
+ handle_ = base::SharedMemory::NULLHandle();
+ length_ = 0;
+
+ volume_received_ = false;
+ volume_ = 0;
+ }
+
+ bool request_packet_received() { return request_packet_received_; }
+ AudioBuffersState buffers_state() { return buffers_state_; }
+
+ bool state_changed_received() { return state_changed_received_; }
+ ViewMsg_AudioStreamState_Params state() { return state_; }
+
+ bool created_received() { return created_received_; }
+ base::SharedMemoryHandle handle() { return handle_; }
+ uint32 length() { return length_; }
+
+ bool volume_received() { return volume_received_; }
+ double volume() { return volume_; }
+
+ private:
+ bool request_packet_received_;
+ AudioBuffersState buffers_state_;
+
+ bool state_changed_received_;
+ ViewMsg_AudioStreamState_Params state_;
+
+ bool created_received_;
+ base::SharedMemoryHandle handle_;
+ uint32 length_;
+
+ bool volume_received_;
+ double volume_;
+
+ DISALLOW_COPY_AND_ASSIGN(MockAudioDelegate);
+};
+
+} // namespace
+
+TEST(AudioMessageFilterTest, Basic) {
+ MessageLoop message_loop(MessageLoop::TYPE_IO);
+
+ const int kRouteId = 0;
+ scoped_refptr<AudioMessageFilter> filter(new AudioMessageFilter(kRouteId));
+
+ MockAudioDelegate delegate;
+ int stream_id = filter->AddDelegate(&delegate);
+
+ // ViewMsg_RequestAudioPacket
+ const int kSizeInBuffer = 1024;
+ AudioBuffersState buffers_state(kSizeInBuffer, 0);
+
+ EXPECT_FALSE(delegate.request_packet_received());
+ filter->OnMessageReceived(ViewMsg_RequestAudioPacket(
+ kRouteId, stream_id, buffers_state));
+ EXPECT_TRUE(delegate.request_packet_received());
+ EXPECT_EQ(kSizeInBuffer, delegate.buffers_state().pending_bytes);
+ EXPECT_EQ(0, delegate.buffers_state().hardware_delay_bytes);
+ EXPECT_TRUE(buffers_state.timestamp == delegate.buffers_state().timestamp);
+ delegate.Reset();
+
+ // ViewMsg_NotifyAudioStreamStateChanged
+ const ViewMsg_AudioStreamState_Params kState(
+ ViewMsg_AudioStreamState_Params::kPlaying);
+ EXPECT_FALSE(delegate.state_changed_received());
+ filter->OnMessageReceived(
+ ViewMsg_NotifyAudioStreamStateChanged(kRouteId, stream_id, kState));
+ EXPECT_TRUE(delegate.state_changed_received());
+ EXPECT_TRUE(kState.state == delegate.state().state);
+ delegate.Reset();
+
+ // ViewMsg_NotifyAudioStreamCreated
+ const uint32 kLength = 1024;
+ EXPECT_FALSE(delegate.created_received());
+ filter->OnMessageReceived(
+ ViewMsg_NotifyAudioStreamCreated(kRouteId,
+ stream_id,
+ base::SharedMemory::NULLHandle(),
+ kLength));
+ EXPECT_TRUE(delegate.created_received());
+ EXPECT_FALSE(base::SharedMemory::IsHandleValid(delegate.handle()));
+ EXPECT_EQ(kLength, delegate.length());
+ delegate.Reset();
+
+ // ViewMsg_NotifyAudioStreamVolume
+ const double kVolume = 1.0;
+ EXPECT_FALSE(delegate.volume_received());
+ filter->OnMessageReceived(
+ ViewMsg_NotifyAudioStreamVolume(kRouteId, stream_id, kVolume));
+ EXPECT_TRUE(delegate.volume_received());
+ EXPECT_EQ(kVolume, delegate.volume());
+ delegate.Reset();
+
+ message_loop.RunAllPending();
+}
+
+TEST(AudioMessageFilterTest, Delegates) {
+ MessageLoop message_loop(MessageLoop::TYPE_IO);
+
+ const int kRouteId = 0;
+ scoped_refptr<AudioMessageFilter> filter(new AudioMessageFilter(kRouteId));
+
+ MockAudioDelegate delegate1;
+ MockAudioDelegate delegate2;
+
+ int stream_id1 = filter->AddDelegate(&delegate1);
+ int stream_id2 = filter->AddDelegate(&delegate2);
+
+ // Send an IPC message. Make sure the correct delegate gets called.
+ EXPECT_FALSE(delegate1.request_packet_received());
+ EXPECT_FALSE(delegate2.request_packet_received());
+ filter->OnMessageReceived(
+ ViewMsg_RequestAudioPacket(kRouteId, stream_id1, AudioBuffersState()));
+ EXPECT_TRUE(delegate1.request_packet_received());
+ EXPECT_FALSE(delegate2.request_packet_received());
+ delegate1.Reset();
+
+ EXPECT_FALSE(delegate1.request_packet_received());
+ EXPECT_FALSE(delegate2.request_packet_received());
+ filter->OnMessageReceived(
+ ViewMsg_RequestAudioPacket(kRouteId, stream_id2, AudioBuffersState()));
+ EXPECT_FALSE(delegate1.request_packet_received());
+ EXPECT_TRUE(delegate2.request_packet_received());
+ delegate2.Reset();
+
+ // Send a message of a different route id, a message is not received.
+ EXPECT_FALSE(delegate1.request_packet_received());
+ filter->OnMessageReceived(
+ ViewMsg_RequestAudioPacket(kRouteId + 1, stream_id1,
+ AudioBuffersState()));
+ EXPECT_FALSE(delegate1.request_packet_received());
+
+ // Remove the delegates. Make sure they won't get called.
+ filter->RemoveDelegate(stream_id1);
+ EXPECT_FALSE(delegate1.request_packet_received());
+ filter->OnMessageReceived(
+ ViewMsg_RequestAudioPacket(kRouteId, stream_id1, AudioBuffersState()));
+ EXPECT_FALSE(delegate1.request_packet_received());
+
+ filter->RemoveDelegate(stream_id2);
+ EXPECT_FALSE(delegate2.request_packet_received());
+ filter->OnMessageReceived(
+ ViewMsg_RequestAudioPacket(kRouteId, stream_id2, AudioBuffersState()));
+ EXPECT_FALSE(delegate2.request_packet_received());
+
+ message_loop.RunAllPending();
+}
diff --git a/content/renderer/cookie_message_filter.cc b/content/renderer/cookie_message_filter.cc
new file mode 100644
index 0000000..06083c1
--- /dev/null
+++ b/content/renderer/cookie_message_filter.cc
@@ -0,0 +1,19 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/cookie_message_filter.h"
+
+#include "chrome/common/render_messages.h"
+
+CookieMessageFilter::CookieMessageFilter()
+ : event_(true, false) {
+}
+
+bool CookieMessageFilter::OnMessageReceived(const IPC::Message& message) {
+ if (message.type() == ViewMsg_SignalCookiePromptEvent::ID) {
+ event_.Signal();
+ return true;
+ }
+ return false;
+}
diff --git a/content/renderer/cookie_message_filter.h b/content/renderer/cookie_message_filter.h
new file mode 100644
index 0000000..3d0f6df
--- /dev/null
+++ b/content/renderer/cookie_message_filter.h
@@ -0,0 +1,30 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_COOKIE_MESSAGE_FILTER_H_
+#define CONTENT_RENDERER_COOKIE_MESSAGE_FILTER_H_
+#pragma once
+
+#include "base/synchronization/waitable_event.h"
+#include "ipc/ipc_channel_proxy.h"
+
+// This class maintains a WaitableEvent that is signaled when an IPC to query
+// cookies from the browser should pump events. Pumping events may be
+// necessary to avoid deadlocks if the browser blocks the cookie query on a
+// user prompt.
+class CookieMessageFilter : public IPC::ChannelProxy::MessageFilter {
+ public:
+ CookieMessageFilter();
+
+ base::WaitableEvent* pump_messages_event() { return &event_; }
+ void ResetPumpMessagesEvent() { event_.Reset(); }
+
+ private:
+ // IPC::ChannelProxy::MessageFilter implementation:
+ virtual bool OnMessageReceived(const IPC::Message& message);
+
+ base::WaitableEvent event_;
+};
+
+#endif // CONTENT_RENDERER_COOKIE_MESSAGE_FILTER_H_
diff --git a/content/renderer/device_orientation_dispatcher.cc b/content/renderer/device_orientation_dispatcher.cc
new file mode 100644
index 0000000..309a3e8
--- /dev/null
+++ b/content/renderer/device_orientation_dispatcher.cc
@@ -0,0 +1,91 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/device_orientation_dispatcher.h"
+
+#include "chrome/common/render_messages.h"
+#include "chrome/common/render_messages_params.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebDeviceOrientation.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebDeviceOrientationController.h"
+
+DeviceOrientationDispatcher::DeviceOrientationDispatcher(
+ RenderView* render_view)
+ : RenderViewObserver(render_view),
+ controller_(NULL),
+ started_(false) {
+}
+
+DeviceOrientationDispatcher::~DeviceOrientationDispatcher() {
+ if (started_)
+ stopUpdating();
+}
+
+bool DeviceOrientationDispatcher::OnMessageReceived(const IPC::Message& msg) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(DeviceOrientationDispatcher, msg)
+ IPC_MESSAGE_HANDLER(ViewMsg_DeviceOrientationUpdated,
+ OnDeviceOrientationUpdated)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+void DeviceOrientationDispatcher::setController(
+ WebKit::WebDeviceOrientationController* controller) {
+ controller_.reset(controller);
+}
+
+void DeviceOrientationDispatcher::startUpdating() {
+ Send(new ViewHostMsg_DeviceOrientation_StartUpdating(routing_id()));
+ started_ = true;
+}
+
+void DeviceOrientationDispatcher::stopUpdating() {
+ Send(new ViewHostMsg_DeviceOrientation_StopUpdating(routing_id()));
+ started_ = false;
+}
+
+WebKit::WebDeviceOrientation DeviceOrientationDispatcher::lastOrientation()
+ const {
+ if (!last_orientation_.get())
+ return WebKit::WebDeviceOrientation::nullOrientation();
+
+ return *last_orientation_;
+}
+
+namespace {
+bool OrientationsEqual(const ViewMsg_DeviceOrientationUpdated_Params& a,
+ WebKit::WebDeviceOrientation* b) {
+ if (a.can_provide_alpha != b->canProvideAlpha())
+ return false;
+ if (a.can_provide_alpha && a.alpha != b->alpha())
+ return false;
+ if (a.can_provide_beta != b->canProvideBeta())
+ return false;
+ if (a.can_provide_beta && a.beta != b->beta())
+ return false;
+ if (a.can_provide_gamma != b->canProvideGamma())
+ return false;
+ if (a.can_provide_gamma && a.gamma != b->gamma())
+ return false;
+
+ return true;
+}
+} // namespace
+
+void DeviceOrientationDispatcher::OnDeviceOrientationUpdated(
+ const ViewMsg_DeviceOrientationUpdated_Params& p) {
+
+ if (last_orientation_.get() && OrientationsEqual(p, last_orientation_.get()))
+ return;
+
+ last_orientation_.reset(new WebKit::WebDeviceOrientation(p.can_provide_alpha,
+ p.alpha,
+ p.can_provide_beta,
+ p.beta,
+ p.can_provide_gamma,
+ p.gamma));
+
+ controller_->didChangeDeviceOrientation(*last_orientation_);
+}
diff --git a/content/renderer/device_orientation_dispatcher.h b/content/renderer/device_orientation_dispatcher.h
new file mode 100644
index 0000000..a50a94f
--- /dev/null
+++ b/content/renderer/device_orientation_dispatcher.h
@@ -0,0 +1,42 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_DEVICE_ORIENTATION_DISPATCHER_H_
+#define CONTENT_RENDERER_DEVICE_ORIENTATION_DISPATCHER_H_
+
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebDeviceOrientationClient.h"
+
+#include "base/scoped_ptr.h"
+#include "chrome/renderer/render_view_observer.h"
+
+namespace WebKit { class WebDeviceOrientation; }
+
+struct ViewMsg_DeviceOrientationUpdated_Params;
+
+class DeviceOrientationDispatcher : public RenderViewObserver,
+ public WebKit::WebDeviceOrientationClient {
+ public:
+ explicit DeviceOrientationDispatcher(RenderView* render_view);
+ virtual ~DeviceOrientationDispatcher();
+
+ private:
+ // RenderView::Observer implementation.
+ virtual bool OnMessageReceived(const IPC::Message& message);
+
+ // From WebKit::WebDeviceOrientationClient.
+ virtual void setController(
+ WebKit::WebDeviceOrientationController* controller);
+ virtual void startUpdating();
+ virtual void stopUpdating();
+ virtual WebKit::WebDeviceOrientation lastOrientation() const;
+
+ void OnDeviceOrientationUpdated(
+ const ViewMsg_DeviceOrientationUpdated_Params& p);
+
+ scoped_ptr<WebKit::WebDeviceOrientationController> controller_;
+ scoped_ptr<WebKit::WebDeviceOrientation> last_orientation_;
+ bool started_;
+};
+
+#endif // CONTENT_RENDERER_DEVICE_ORIENTATION_DISPATCHER_H_
diff --git a/content/renderer/geolocation_dispatcher.cc b/content/renderer/geolocation_dispatcher.cc
new file mode 100644
index 0000000..0934aad
--- /dev/null
+++ b/content/renderer/geolocation_dispatcher.cc
@@ -0,0 +1,149 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/geolocation_dispatcher.h"
+
+#include "chrome/common/render_messages.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebGeolocationPermissionRequest.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebGeolocationPermissionRequestManager.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebGeolocationClient.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebGeolocationPosition.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebGeolocationError.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h"
+
+using namespace WebKit;
+
+GeolocationDispatcher::GeolocationDispatcher(RenderView* render_view)
+ : RenderViewObserver(render_view),
+ pending_permissions_(new WebGeolocationPermissionRequestManager()),
+ enable_high_accuracy_(false),
+ updating_(false) {
+}
+
+GeolocationDispatcher::~GeolocationDispatcher() {}
+
+bool GeolocationDispatcher::OnMessageReceived(const IPC::Message& message) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(GeolocationDispatcher, message)
+ IPC_MESSAGE_HANDLER(ViewMsg_Geolocation_PermissionSet,
+ OnGeolocationPermissionSet)
+ IPC_MESSAGE_HANDLER(ViewMsg_Geolocation_PositionUpdated,
+ OnGeolocationPositionUpdated)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+void GeolocationDispatcher::geolocationDestroyed() {
+ controller_.reset();
+ DCHECK(!updating_);
+}
+
+void GeolocationDispatcher::startUpdating() {
+ GURL url;
+ Send(new ViewHostMsg_Geolocation_StartUpdating(
+ routing_id(), url, enable_high_accuracy_));
+ updating_ = true;
+}
+
+void GeolocationDispatcher::stopUpdating() {
+ Send(new ViewHostMsg_Geolocation_StopUpdating(routing_id()));
+ updating_ = false;
+}
+
+void GeolocationDispatcher::setEnableHighAccuracy(bool enable_high_accuracy) {
+ // GeolocationController calls setEnableHighAccuracy(true) before
+ // startUpdating in response to the first high-accuracy Geolocation
+ // subscription. When the last high-accuracy Geolocation unsubscribes
+ // it calls setEnableHighAccuracy(false) after stopUpdating.
+ bool has_changed = enable_high_accuracy_ != enable_high_accuracy;
+ enable_high_accuracy_ = enable_high_accuracy;
+ // We have a different accuracy requirement. Request browser to update.
+ if (updating_ && has_changed)
+ startUpdating();
+}
+
+void GeolocationDispatcher::setController(
+ WebGeolocationController* controller) {
+ controller_.reset(controller);
+}
+
+bool GeolocationDispatcher::lastPosition(WebGeolocationPosition&) {
+ // The latest position is stored in the browser, not the renderer, so we
+ // would have to fetch it synchronously to give a good value here. The
+ // WebCore::GeolocationController already caches the last position it
+ // receives, so there is not much benefit to more position caching here.
+ return false;
+}
+
+// TODO(jknotten): Change the messages to use a security origin, so no
+// conversion is necessary.
+void GeolocationDispatcher::requestPermission(
+ const WebGeolocationPermissionRequest& permissionRequest) {
+ int bridge_id = pending_permissions_->add(permissionRequest);
+ string16 origin = permissionRequest.securityOrigin().toString();
+ Send(new ViewHostMsg_Geolocation_RequestPermission(
+ routing_id(), bridge_id, GURL(origin)));
+}
+
+// TODO(jknotten): Change the messages to use a security origin, so no
+// conversion is necessary.
+void GeolocationDispatcher::cancelPermissionRequest(
+ const WebGeolocationPermissionRequest& permissionRequest) {
+ int bridge_id;
+ if (!pending_permissions_->remove(permissionRequest, bridge_id))
+ return;
+ string16 origin = permissionRequest.securityOrigin().toString();
+ Send(new ViewHostMsg_Geolocation_CancelPermissionRequest(
+ routing_id(), bridge_id, GURL(origin)));
+}
+
+// Permission for using geolocation has been set.
+void GeolocationDispatcher::OnGeolocationPermissionSet(
+ int bridge_id, bool is_allowed) {
+ WebGeolocationPermissionRequest permissionRequest;
+ if (!pending_permissions_->remove(bridge_id, permissionRequest))
+ return;
+ permissionRequest.setIsAllowed(is_allowed);
+}
+
+// We have an updated geolocation position or error code.
+void GeolocationDispatcher::OnGeolocationPositionUpdated(
+ const Geoposition& geoposition) {
+ // It is possible for the browser process to have queued an update message
+ // before receiving the stop updating message.
+ if (!updating_)
+ return;
+
+ DCHECK(geoposition.IsInitialized());
+ if (geoposition.IsValidFix()) {
+ controller_->positionChanged(
+ WebGeolocationPosition(
+ geoposition.timestamp.ToDoubleT(),
+ geoposition.latitude, geoposition.longitude,
+ geoposition.accuracy,
+ geoposition.is_valid_altitude(), geoposition.altitude,
+ geoposition.is_valid_altitude_accuracy(),
+ geoposition.altitude_accuracy,
+ geoposition.is_valid_heading(), geoposition.heading,
+ geoposition.is_valid_speed(), geoposition.speed));
+ } else {
+ WebGeolocationError::Error code;
+ switch (geoposition.error_code) {
+ case Geoposition::ERROR_CODE_PERMISSION_DENIED:
+ code = WebGeolocationError::ErrorPermissionDenied;
+ break;
+ case Geoposition::ERROR_CODE_POSITION_UNAVAILABLE:
+ code = WebGeolocationError::ErrorPositionUnavailable;
+ break;
+ default:
+ DCHECK(false);
+ NOTREACHED() << geoposition.error_code;
+ return;
+ }
+ controller_->errorOccurred(
+ WebGeolocationError(
+ code, WebKit::WebString::fromUTF8(geoposition.error_message)));
+ }
+}
diff --git a/content/renderer/geolocation_dispatcher.h b/content/renderer/geolocation_dispatcher.h
new file mode 100644
index 0000000..2189946
--- /dev/null
+++ b/content/renderer/geolocation_dispatcher.h
@@ -0,0 +1,66 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_GEOLOCATION_DISPATCHER_H_
+#define CONTENT_RENDERER_GEOLOCATION_DISPATCHER_H_
+#pragma once
+
+#include "base/scoped_ptr.h"
+#include "chrome/renderer/render_view_observer.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebGeolocationClient.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebGeolocationController.h"
+
+struct Geoposition;
+
+namespace WebKit {
+class WebGeolocationController;
+class WebGeolocationPermissionRequest;
+class WebGeolocationPermissionRequestManager;
+class WebGeolocationPosition;
+class WebSecurityOrigin;
+}
+
+// GeolocationDispatcher is a delegate for Geolocation messages used by
+// WebKit.
+// It's the complement of GeolocationDispatcherHost (owned by RenderViewHost).
+class GeolocationDispatcher : public RenderViewObserver,
+ public WebKit::WebGeolocationClient {
+ public:
+ explicit GeolocationDispatcher(RenderView* render_view);
+ virtual ~GeolocationDispatcher();
+
+ private:
+ // RenderView::Observer implementation.
+ virtual bool OnMessageReceived(const IPC::Message& message);
+
+ // WebGeolocationClient
+ virtual void geolocationDestroyed();
+ virtual void startUpdating();
+ virtual void stopUpdating();
+ virtual void setEnableHighAccuracy(bool enable_high_accuracy);
+ virtual void setController(WebKit::WebGeolocationController* controller);
+ virtual bool lastPosition(WebKit::WebGeolocationPosition& position);
+ virtual void requestPermission(
+ const WebKit::WebGeolocationPermissionRequest& permissionRequest);
+ virtual void cancelPermissionRequest(
+ const WebKit::WebGeolocationPermissionRequest& permissionRequest);
+
+ // Permission for using geolocation has been set.
+ void OnGeolocationPermissionSet(int bridge_id, bool is_allowed);
+
+ // We have an updated geolocation position or error code.
+ void OnGeolocationPositionUpdated(const Geoposition& geoposition);
+
+ // The controller_ is valid for the lifetime of the underlying
+ // WebCore::GeolocationController. geolocationDestroyed() is
+ // invoked when the underlying object is destroyed.
+ scoped_ptr< WebKit::WebGeolocationController> controller_;
+
+ scoped_ptr<WebKit::WebGeolocationPermissionRequestManager>
+ pending_permissions_;
+ bool enable_high_accuracy_;
+ bool updating_;
+};
+
+#endif // CONTENT_RENDERER_GEOLOCATION_DISPATCHER_H_
diff --git a/content/renderer/indexed_db_dispatcher.cc b/content/renderer/indexed_db_dispatcher.cc
new file mode 100644
index 0000000..d62ad6f
--- /dev/null
+++ b/content/renderer/indexed_db_dispatcher.cc
@@ -0,0 +1,455 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/indexed_db_dispatcher.h"
+
+#include "chrome/renderer/render_thread.h"
+#include "chrome/renderer/render_view.h"
+#include "chrome/renderer/renderer_webidbcursor_impl.h"
+#include "chrome/renderer/renderer_webidbdatabase_impl.h"
+#include "chrome/renderer/renderer_webidbindex_impl.h"
+#include "chrome/renderer/renderer_webidbobjectstore_impl.h"
+#include "chrome/renderer/renderer_webidbtransaction_impl.h"
+#include "content/common/indexed_db_messages.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBDatabaseCallbacks.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBDatabaseError.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBKeyRange.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebSerializedScriptValue.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h"
+
+using WebKit::WebExceptionCode;
+using WebKit::WebFrame;
+using WebKit::WebIDBCallbacks;
+using WebKit::WebIDBKeyRange;
+using WebKit::WebIDBDatabase;
+using WebKit::WebIDBDatabaseCallbacks;
+using WebKit::WebIDBDatabaseError;
+using WebKit::WebIDBTransaction;
+using WebKit::WebIDBTransactionCallbacks;
+
+IndexedDBDispatcher::IndexedDBDispatcher() {
+}
+
+IndexedDBDispatcher::~IndexedDBDispatcher() {
+}
+
+bool IndexedDBDispatcher::OnMessageReceived(const IPC::Message& msg) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(IndexedDBDispatcher, msg)
+ IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessIDBCursor,
+ OnSuccessOpenCursor)
+ IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessIDBDatabase,
+ OnSuccessIDBDatabase)
+ IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessIDBIndex,
+ OnSuccessIDBIndex)
+ IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessIndexedDBKey,
+ OnSuccessIndexedDBKey)
+ IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessIDBTransaction,
+ OnSuccessIDBTransaction)
+ IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessSerializedScriptValue,
+ OnSuccessSerializedScriptValue)
+ IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksError, OnError)
+ IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksBlocked, OnBlocked)
+ IPC_MESSAGE_HANDLER(IndexedDBMsg_TransactionCallbacksAbort, OnAbort)
+ IPC_MESSAGE_HANDLER(IndexedDBMsg_TransactionCallbacksComplete, OnComplete)
+ IPC_MESSAGE_HANDLER(IndexedDBMsg_TransactionCallbacksTimeout, OnTimeout)
+ IPC_MESSAGE_HANDLER(IndexedDBMsg_DatabaseCallbacksVersionChange,
+ OnVersionChange)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+void IndexedDBDispatcher::RequestIDBCursorUpdate(
+ const SerializedScriptValue& value,
+ WebIDBCallbacks* callbacks_ptr,
+ int32 idb_cursor_id,
+ WebExceptionCode* ec) {
+ scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
+
+ int32 response_id = pending_callbacks_.Add(callbacks.release());
+ RenderThread::current()->Send(
+ new IndexedDBHostMsg_CursorUpdate(idb_cursor_id, response_id, value, ec));
+ if (*ec)
+ pending_callbacks_.Remove(response_id);
+}
+
+void IndexedDBDispatcher::RequestIDBCursorContinue(
+ const IndexedDBKey& key,
+ WebIDBCallbacks* callbacks_ptr,
+ int32 idb_cursor_id,
+ WebExceptionCode* ec) {
+ scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
+
+ int32 response_id = pending_callbacks_.Add(callbacks.release());
+ RenderThread::current()->Send(
+ new IndexedDBHostMsg_CursorContinue(idb_cursor_id, response_id, key, ec));
+ if (*ec)
+ pending_callbacks_.Remove(response_id);
+}
+
+void IndexedDBDispatcher::RequestIDBCursorDelete(
+ WebIDBCallbacks* callbacks_ptr,
+ int32 idb_cursor_id,
+ WebExceptionCode* ec) {
+ scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
+
+ int32 response_id = pending_callbacks_.Add(callbacks.release());
+ RenderThread::current()->Send(
+ new IndexedDBHostMsg_CursorDelete(idb_cursor_id, response_id, ec));
+ if (*ec)
+ pending_callbacks_.Remove(response_id);
+}
+
+void IndexedDBDispatcher::RequestIDBFactoryOpen(
+ const string16& name,
+ WebIDBCallbacks* callbacks_ptr,
+ const string16& origin,
+ WebFrame* web_frame,
+ uint64 maximum_size) {
+ scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
+
+ if (!web_frame)
+ return; // We must be shutting down.
+ RenderView* render_view = RenderView::FromWebView(web_frame->view());
+ if (!render_view)
+ return; // We must be shutting down.
+
+ IndexedDBHostMsg_FactoryOpen_Params params;
+ params.routing_id = render_view->routing_id();
+ params.response_id = pending_callbacks_.Add(callbacks.release());
+ params.origin = origin;
+ params.name = name;
+ params.maximum_size = maximum_size;
+ RenderThread::current()->Send(new IndexedDBHostMsg_FactoryOpen(params));
+}
+
+void IndexedDBDispatcher::RequestIDBFactoryDeleteDatabase(
+ const string16& name,
+ WebIDBCallbacks* callbacks_ptr,
+ const string16& origin,
+ WebFrame* web_frame) {
+ scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
+
+ if (!web_frame)
+ return; // We must be shutting down.
+ RenderView* render_view = RenderView::FromWebView(web_frame->view());
+ if (!render_view)
+ return; // We must be shutting down.
+
+ IndexedDBHostMsg_FactoryDeleteDatabase_Params params;
+ params.routing_id = render_view->routing_id();
+ params.response_id = pending_callbacks_.Add(callbacks.release());
+ params.origin = origin;
+ params.name = name;
+ RenderThread::current()->Send(
+ new IndexedDBHostMsg_FactoryDeleteDatabase(params));
+}
+
+void IndexedDBDispatcher::RequestIDBDatabaseClose(int32 idb_database_id) {
+ RenderThread::current()->Send(
+ new IndexedDBHostMsg_DatabaseClose(idb_database_id));
+ pending_database_callbacks_.Remove(idb_database_id);
+}
+
+ void IndexedDBDispatcher::RequestIDBDatabaseOpen(
+ WebIDBDatabaseCallbacks* callbacks_ptr,
+ int32 idb_database_id) {
+ scoped_ptr<WebIDBDatabaseCallbacks> callbacks(callbacks_ptr);
+
+ int32 response_id = pending_database_callbacks_.Add(callbacks.release());
+ RenderThread::current()->Send(new IndexedDBHostMsg_DatabaseOpen(response_id,
+ idb_database_id));
+}
+
+void IndexedDBDispatcher::RequestIDBDatabaseSetVersion(
+ const string16& version,
+ WebIDBCallbacks* callbacks_ptr,
+ int32 idb_database_id,
+ WebExceptionCode* ec) {
+ scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
+
+ int32 response_id = pending_callbacks_.Add(callbacks.release());
+ RenderThread::current()->Send(
+ new IndexedDBHostMsg_DatabaseSetVersion(idb_database_id, response_id,
+ version, ec));
+ if (*ec)
+ pending_callbacks_.Remove(response_id);
+}
+
+void IndexedDBDispatcher::RequestIDBIndexOpenObjectCursor(
+ const WebIDBKeyRange& idb_key_range,
+ unsigned short direction,
+ WebIDBCallbacks* callbacks_ptr,
+ int32 idb_index_id,
+ const WebIDBTransaction& transaction,
+ WebExceptionCode* ec) {
+ scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
+ IndexedDBHostMsg_IndexOpenCursor_Params params;
+ params.response_id = pending_callbacks_.Add(callbacks.release());
+ params.lower_key.Set(idb_key_range.lower());
+ params.upper_key.Set(idb_key_range.upper());
+ params.lower_open = idb_key_range.lowerOpen();
+ params.upper_open = idb_key_range.upperOpen();
+ params.direction = direction;
+ params.idb_index_id = idb_index_id;
+ params.transaction_id = TransactionId(transaction);
+ RenderThread::current()->Send(
+ new IndexedDBHostMsg_IndexOpenObjectCursor(params, ec));
+ if (*ec)
+ pending_callbacks_.Remove(params.response_id);
+}
+
+void IndexedDBDispatcher::RequestIDBIndexOpenKeyCursor(
+ const WebIDBKeyRange& idb_key_range,
+ unsigned short direction,
+ WebIDBCallbacks* callbacks_ptr,
+ int32 idb_index_id,
+ const WebIDBTransaction& transaction,
+ WebExceptionCode* ec) {
+ scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
+ IndexedDBHostMsg_IndexOpenCursor_Params params;
+ params.response_id = pending_callbacks_.Add(callbacks.release());
+ // TODO(jorlow): We really should just create a Chromium abstraction for
+ // KeyRange rather than doing it ad-hoc like this.
+ params.lower_key.Set(idb_key_range.lower());
+ params.upper_key.Set(idb_key_range.upper());
+ params.lower_open = idb_key_range.lowerOpen();
+ params.upper_open = idb_key_range.upperOpen();
+ params.direction = direction;
+ params.idb_index_id = idb_index_id;
+ params.transaction_id = TransactionId(transaction);
+ RenderThread::current()->Send(
+ new IndexedDBHostMsg_IndexOpenKeyCursor(params, ec));
+ if (*ec)
+ pending_callbacks_.Remove(params.response_id);
+}
+
+void IndexedDBDispatcher::RequestIDBIndexGetObject(
+ const IndexedDBKey& key,
+ WebIDBCallbacks* callbacks_ptr,
+ int32 idb_index_id,
+ const WebIDBTransaction& transaction,
+ WebExceptionCode* ec) {
+ scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
+ int32 response_id = pending_callbacks_.Add(callbacks.release());
+ RenderThread::current()->Send(
+ new IndexedDBHostMsg_IndexGetObject(
+ idb_index_id, response_id, key,
+ TransactionId(transaction), ec));
+ if (*ec)
+ pending_callbacks_.Remove(response_id);
+}
+
+void IndexedDBDispatcher::RequestIDBIndexGetKey(
+ const IndexedDBKey& key,
+ WebIDBCallbacks* callbacks_ptr,
+ int32 idb_index_id,
+ const WebIDBTransaction& transaction,
+ WebExceptionCode* ec) {
+ scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
+ int32 response_id = pending_callbacks_.Add(callbacks.release());
+ RenderThread::current()->Send(
+ new IndexedDBHostMsg_IndexGetKey(
+ idb_index_id, response_id, key,
+ TransactionId(transaction), ec));
+ if (*ec)
+ pending_callbacks_.Remove(response_id);
+}
+
+void IndexedDBDispatcher::RequestIDBObjectStoreGet(
+ const IndexedDBKey& key,
+ WebIDBCallbacks* callbacks_ptr,
+ int32 idb_object_store_id,
+ const WebIDBTransaction& transaction,
+ WebExceptionCode* ec) {
+ scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
+
+ int32 response_id = pending_callbacks_.Add(callbacks.release());
+ RenderThread::current()->Send(
+ new IndexedDBHostMsg_ObjectStoreGet(
+ idb_object_store_id, response_id,
+ key, TransactionId(transaction), ec));
+ if (*ec)
+ pending_callbacks_.Remove(response_id);
+}
+
+void IndexedDBDispatcher::RequestIDBObjectStorePut(
+ const SerializedScriptValue& value,
+ const IndexedDBKey& key,
+ WebKit::WebIDBObjectStore::PutMode put_mode,
+ WebIDBCallbacks* callbacks_ptr,
+ int32 idb_object_store_id,
+ const WebIDBTransaction& transaction,
+ WebExceptionCode* ec) {
+ scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
+ IndexedDBHostMsg_ObjectStorePut_Params params;
+ params.idb_object_store_id = idb_object_store_id;
+ params.response_id = pending_callbacks_.Add(callbacks.release());
+ params.serialized_value = value;
+ params.key = key;
+ params.put_mode = put_mode;
+ params.transaction_id = TransactionId(transaction);
+ RenderThread::current()->Send(new IndexedDBHostMsg_ObjectStorePut(
+ params, ec));
+ if (*ec)
+ pending_callbacks_.Remove(params.response_id);
+}
+
+void IndexedDBDispatcher::RequestIDBObjectStoreDelete(
+ const IndexedDBKey& key,
+ WebIDBCallbacks* callbacks_ptr,
+ int32 idb_object_store_id,
+ const WebIDBTransaction& transaction,
+ WebExceptionCode* ec) {
+ scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
+
+ int32 response_id = pending_callbacks_.Add(callbacks.release());
+ RenderThread::current()->Send(
+ new IndexedDBHostMsg_ObjectStoreDelete(
+ idb_object_store_id, response_id,
+ key, TransactionId(transaction), ec));
+ if (*ec)
+ pending_callbacks_.Remove(response_id);
+}
+
+void IndexedDBDispatcher::RequestIDBObjectStoreClear(
+ WebIDBCallbacks* callbacks_ptr,
+ int32 idb_object_store_id,
+ const WebIDBTransaction& transaction,
+ WebExceptionCode* ec) {
+ scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
+
+ int32 response_id = pending_callbacks_.Add(callbacks.release());
+ RenderThread::current()->Send(
+ new IndexedDBHostMsg_ObjectStoreClear(
+ idb_object_store_id, response_id,
+ TransactionId(transaction), ec));
+ if (*ec)
+ pending_callbacks_.Remove(response_id);
+}
+
+void IndexedDBDispatcher::RequestIDBObjectStoreOpenCursor(
+ const WebIDBKeyRange& idb_key_range,
+ unsigned short direction,
+ WebIDBCallbacks* callbacks_ptr,
+ int32 idb_object_store_id,
+ const WebIDBTransaction& transaction,
+ WebExceptionCode* ec) {
+ scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
+ IndexedDBHostMsg_ObjectStoreOpenCursor_Params params;
+ params.response_id = pending_callbacks_.Add(callbacks.release());
+ params.lower_key.Set(idb_key_range.lower());
+ params.upper_key.Set(idb_key_range.upper());
+ params.lower_open = idb_key_range.lowerOpen();
+ params.upper_open = idb_key_range.upperOpen();
+ params.direction = direction;
+ params.idb_object_store_id = idb_object_store_id;
+ params.transaction_id = TransactionId(transaction);
+ RenderThread::current()->Send(
+ new IndexedDBHostMsg_ObjectStoreOpenCursor(params, ec));
+ if (*ec)
+ pending_callbacks_.Remove(params.response_id);
+}
+
+void IndexedDBDispatcher::RegisterWebIDBTransactionCallbacks(
+ WebIDBTransactionCallbacks* callbacks,
+ int32 id) {
+ pending_transaction_callbacks_.AddWithID(callbacks, id);
+}
+
+int32 IndexedDBDispatcher::TransactionId(
+ const WebIDBTransaction& transaction) {
+ const RendererWebIDBTransactionImpl* impl =
+ static_cast<const RendererWebIDBTransactionImpl*>(&transaction);
+ return impl->id();
+}
+
+void IndexedDBDispatcher::OnSuccessIDBDatabase(int32 response_id,
+ int32 object_id) {
+ WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(response_id);
+ callbacks->onSuccess(new RendererWebIDBDatabaseImpl(object_id));
+ pending_callbacks_.Remove(response_id);
+}
+
+void IndexedDBDispatcher::OnSuccessIndexedDBKey(int32 response_id,
+ const IndexedDBKey& key) {
+ WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(response_id);
+ callbacks->onSuccess(key);
+ pending_callbacks_.Remove(response_id);
+}
+
+void IndexedDBDispatcher::OnSuccessIDBTransaction(int32 response_id,
+ int32 object_id) {
+ WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(response_id);
+ callbacks->onSuccess(new RendererWebIDBTransactionImpl(object_id));
+ pending_callbacks_.Remove(response_id);
+}
+
+void IndexedDBDispatcher::OnSuccessIDBIndex(int32 response_id,
+ int32 object_id) {
+ WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(response_id);
+ callbacks->onSuccess(new RendererWebIDBIndexImpl(object_id));
+ pending_callbacks_.Remove(response_id);
+}
+
+void IndexedDBDispatcher::OnSuccessSerializedScriptValue(
+ int32 response_id, const SerializedScriptValue& value) {
+ WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(response_id);
+ callbacks->onSuccess(value);
+ pending_callbacks_.Remove(response_id);
+}
+
+void IndexedDBDispatcher::OnSuccessOpenCursor(int32 repsonse_id,
+ int32 object_id) {
+ WebIDBCallbacks* callbacks =
+ pending_callbacks_.Lookup(repsonse_id);
+ callbacks->onSuccess(new RendererWebIDBCursorImpl(object_id));
+ pending_callbacks_.Remove(repsonse_id);
+}
+
+void IndexedDBDispatcher::OnBlocked(int32 response_id) {
+ WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(response_id);
+ callbacks->onBlocked();
+}
+
+void IndexedDBDispatcher::OnError(int32 response_id, int code,
+ const string16& message) {
+ WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(response_id);
+ callbacks->onError(WebIDBDatabaseError(code, message));
+ pending_callbacks_.Remove(response_id);
+}
+
+void IndexedDBDispatcher::OnAbort(int32 transaction_id) {
+ WebIDBTransactionCallbacks* callbacks =
+ pending_transaction_callbacks_.Lookup(transaction_id);
+ callbacks->onAbort();
+ pending_transaction_callbacks_.Remove(transaction_id);
+}
+
+void IndexedDBDispatcher::OnComplete(int32 transaction_id) {
+ WebIDBTransactionCallbacks* callbacks =
+ pending_transaction_callbacks_.Lookup(transaction_id);
+ callbacks->onComplete();
+ pending_transaction_callbacks_.Remove(transaction_id);
+}
+
+void IndexedDBDispatcher::OnTimeout(int32 transaction_id) {
+ WebIDBTransactionCallbacks* callbacks =
+ pending_transaction_callbacks_.Lookup(transaction_id);
+ callbacks->onTimeout();
+ pending_transaction_callbacks_.Remove(transaction_id);
+}
+
+void IndexedDBDispatcher::OnVersionChange(int32 database_id,
+ const string16& newVersion) {
+ WebIDBDatabaseCallbacks* callbacks =
+ pending_database_callbacks_.Lookup(database_id);
+ // callbacks would be NULL if a versionchange event is received after close
+ // has been called.
+ if (callbacks)
+ callbacks->onVersionChange(newVersion);
+}
diff --git a/content/renderer/indexed_db_dispatcher.h b/content/renderer/indexed_db_dispatcher.h
new file mode 100644
index 0000000..b019510
--- /dev/null
+++ b/content/renderer/indexed_db_dispatcher.h
@@ -0,0 +1,176 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_INDEXED_DB_DISPATCHER_H_
+#define CONTENT_RENDERER_INDEXED_DB_DISPATCHER_H_
+#pragma once
+
+#include "base/id_map.h"
+#include "base/nullable_string16.h"
+#include "ipc/ipc_channel.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebExceptionCode.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBCallbacks.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBDatabase.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBObjectStore.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBTransactionCallbacks.h"
+
+class IndexedDBKey;
+class SerializedScriptValue;
+
+namespace WebKit {
+class WebFrame;
+class WebIDBKeyRange;
+class WebIDBTransaction;
+}
+
+// Handle the indexed db related communication for this entire renderer.
+class IndexedDBDispatcher : public IPC::Channel::Listener {
+ public:
+ IndexedDBDispatcher();
+ ~IndexedDBDispatcher();
+
+ // IPC::Channel::Listener implementation.
+ virtual bool OnMessageReceived(const IPC::Message& msg);
+
+ void RequestIDBFactoryOpen(
+ const string16& name,
+ WebKit::WebIDBCallbacks* callbacks,
+ const string16& origin,
+ WebKit::WebFrame* web_frame,
+ uint64 maximum_size);
+
+ void RequestIDBFactoryDeleteDatabase(
+ const string16& name,
+ WebKit::WebIDBCallbacks* callbacks,
+ const string16& origin,
+ WebKit::WebFrame* web_frame);
+
+ void RequestIDBCursorUpdate(
+ const SerializedScriptValue& value,
+ WebKit::WebIDBCallbacks* callbacks_ptr,
+ int32 idb_cursor_id,
+ WebKit::WebExceptionCode* ec);
+
+ void RequestIDBCursorContinue(
+ const IndexedDBKey& key,
+ WebKit::WebIDBCallbacks* callbacks_ptr,
+ int32 idb_cursor_id,
+ WebKit::WebExceptionCode* ec);
+
+ void RequestIDBCursorDelete(
+ WebKit::WebIDBCallbacks* callbacks_ptr,
+ int32 idb_cursor_id,
+ WebKit::WebExceptionCode* ec);
+
+ void RequestIDBDatabaseClose(
+ int32 idb_database_id);
+
+ void RequestIDBDatabaseOpen(
+ WebKit::WebIDBDatabaseCallbacks* callbacks_ptr,
+ int32 idb_database_id);
+
+ void RequestIDBDatabaseSetVersion(
+ const string16& version,
+ WebKit::WebIDBCallbacks* callbacks,
+ int32 idb_database_id,
+ WebKit::WebExceptionCode* ec);
+
+ void RequestIDBIndexOpenObjectCursor(
+ const WebKit::WebIDBKeyRange& idb_key_range,
+ unsigned short direction,
+ WebKit::WebIDBCallbacks* callbacks,
+ int32 idb_index_id,
+ const WebKit::WebIDBTransaction& transaction,
+ WebKit::WebExceptionCode* ec);
+
+ void RequestIDBIndexOpenKeyCursor(
+ const WebKit::WebIDBKeyRange& idb_key_range,
+ unsigned short direction,
+ WebKit::WebIDBCallbacks* callbacks,
+ int32 idb_index_id,
+ const WebKit::WebIDBTransaction& transaction,
+ WebKit::WebExceptionCode* ec);
+
+ void RequestIDBIndexGetObject(const IndexedDBKey& key,
+ WebKit::WebIDBCallbacks* callbacks,
+ int32 idb_index_id,
+ const WebKit::WebIDBTransaction& transaction,
+ WebKit::WebExceptionCode* ec);
+
+ void RequestIDBIndexGetKey(const IndexedDBKey& key,
+ WebKit::WebIDBCallbacks* callbacks,
+ int32 idb_index_id,
+ const WebKit::WebIDBTransaction& transaction,
+ WebKit::WebExceptionCode* ec);
+
+ void RequestIDBObjectStoreGet(const IndexedDBKey& key,
+ WebKit::WebIDBCallbacks* callbacks,
+ int32 idb_object_store_id,
+ const WebKit::WebIDBTransaction& transaction,
+ WebKit::WebExceptionCode* ec);
+
+ void RequestIDBObjectStorePut(const SerializedScriptValue& value,
+ const IndexedDBKey& key,
+ WebKit::WebIDBObjectStore::PutMode putMode,
+ WebKit::WebIDBCallbacks* callbacks,
+ int32 idb_object_store_id,
+ const WebKit::WebIDBTransaction& transaction,
+ WebKit::WebExceptionCode* ec);
+
+ void RequestIDBObjectStoreDelete(
+ const IndexedDBKey& key,
+ WebKit::WebIDBCallbacks* callbacks,
+ int32 idb_object_store_id,
+ const WebKit::WebIDBTransaction& transaction,
+ WebKit::WebExceptionCode* ec);
+
+ void RequestIDBObjectStoreClear(
+ WebKit::WebIDBCallbacks* callbacks,
+ int32 idb_object_store_id,
+ const WebKit::WebIDBTransaction& transaction,
+ WebKit::WebExceptionCode* ec);
+
+ void RequestIDBObjectStoreOpenCursor(
+ const WebKit::WebIDBKeyRange& idb_key_range,
+ unsigned short direction,
+ WebKit::WebIDBCallbacks* callbacks,
+ int32 idb_object_store_id,
+ const WebKit::WebIDBTransaction& transaction,
+ WebKit::WebExceptionCode* ec);
+
+ void RegisterWebIDBTransactionCallbacks(
+ WebKit::WebIDBTransactionCallbacks* callbacks,
+ int32 id);
+
+ static int32 TransactionId(const WebKit::WebIDBTransaction& transaction);
+
+ private:
+ // IDBCallback message handlers.
+ void OnSuccessNull(int32 response_id);
+ void OnSuccessIDBDatabase(int32 response_id, int32 object_id);
+ void OnSuccessIndexedDBKey(int32 response_id, const IndexedDBKey& key);
+ void OnSuccessIDBTransaction(int32 response_id, int32 object_id);
+ void OnSuccessIDBIndex(int32 response_id, int32 object_id);
+ void OnSuccessOpenCursor(int32 response_id, int32 object_id);
+ void OnSuccessSerializedScriptValue(int32 response_id,
+ const SerializedScriptValue& value);
+ void OnError(int32 response_id, int code, const string16& message);
+ void OnBlocked(int32 response_id);
+ void OnAbort(int32 transaction_id);
+ void OnComplete(int32 transaction_id);
+ void OnTimeout(int32 transaction_id);
+ void OnVersionChange(int32 database_id, const string16& newVersion);
+
+ // Careful! WebIDBCallbacks wraps non-threadsafe data types. It must be
+ // destroyed and used on the same thread it was created on.
+ IDMap<WebKit::WebIDBCallbacks, IDMapOwnPointer> pending_callbacks_;
+ IDMap<WebKit::WebIDBTransactionCallbacks, IDMapOwnPointer>
+ pending_transaction_callbacks_;
+ IDMap<WebKit::WebIDBDatabaseCallbacks, IDMapOwnPointer>
+ pending_database_callbacks_;
+
+ DISALLOW_COPY_AND_ASSIGN(IndexedDBDispatcher);
+};
+
+#endif // CONTENT_RENDERER_INDEXED_DB_DISPATCHER_H_
diff --git a/content/renderer/media/audio_renderer_impl.cc b/content/renderer/media/audio_renderer_impl.cc
index 86338e9..411a1d6 100644
--- a/content/renderer/media/audio_renderer_impl.cc
+++ b/content/renderer/media/audio_renderer_impl.cc
@@ -8,7 +8,6 @@
#include "chrome/common/render_messages.h"
#include "chrome/common/render_messages_params.h"
-#include "chrome/renderer/audio_message_filter.h"
#include "chrome/renderer/render_view.h"
#include "chrome/renderer/render_thread.h"
#include "media/base/filter_host.h"
diff --git a/content/renderer/media/audio_renderer_impl.h b/content/renderer/media/audio_renderer_impl.h
index c9f11a3..adb9674 100644
--- a/content/renderer/media/audio_renderer_impl.h
+++ b/content/renderer/media/audio_renderer_impl.h
@@ -43,7 +43,7 @@
#include "base/scoped_ptr.h"
#include "base/shared_memory.h"
#include "base/synchronization/lock.h"
-#include "chrome/renderer/audio_message_filter.h"
+#include "content/renderer/audio_message_filter.h"
#include "media/audio/audio_io.h"
#include "media/audio/audio_manager.h"
#include "media/base/filters.h"
diff --git a/content/renderer/notification_provider.cc b/content/renderer/notification_provider.cc
new file mode 100644
index 0000000..73633fc
--- /dev/null
+++ b/content/renderer/notification_provider.cc
@@ -0,0 +1,188 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/notification_provider.h"
+
+#include "base/string_util.h"
+#include "base/task.h"
+#include "chrome/common/render_messages.h"
+#include "chrome/common/render_messages_params.h"
+#include "chrome/common/url_constants.h"
+#include "chrome/renderer/render_thread.h"
+#include "chrome/renderer/render_view.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebNotificationPermissionCallback.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebURL.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
+
+using WebKit::WebDocument;
+using WebKit::WebNotification;
+using WebKit::WebNotificationPresenter;
+using WebKit::WebNotificationPermissionCallback;
+using WebKit::WebSecurityOrigin;
+using WebKit::WebString;
+using WebKit::WebURL;
+
+NotificationProvider::NotificationProvider(RenderView* render_view)
+ : RenderViewObserver(render_view) {
+}
+
+NotificationProvider::~NotificationProvider() {
+ manager_.DetachAll();
+}
+
+bool NotificationProvider::show(const WebNotification& notification) {
+ int notification_id = manager_.RegisterNotification(notification);
+ if (notification.isHTML())
+ return ShowHTML(notification, notification_id);
+ else
+ return ShowText(notification, notification_id);
+}
+
+void NotificationProvider::cancel(const WebNotification& notification) {
+ int id;
+ bool id_found = manager_.GetId(notification, id);
+ // Won't be found if the notification has already been closed by the user.
+ if (id_found)
+ Send(new ViewHostMsg_CancelDesktopNotification(routing_id(), id));
+}
+
+void NotificationProvider::objectDestroyed(
+ const WebNotification& notification) {
+ int id;
+ bool id_found = manager_.GetId(notification, id);
+ // Won't be found if the notification has already been closed by the user.
+ if (id_found)
+ manager_.UnregisterNotification(id);
+}
+
+WebNotificationPresenter::Permission NotificationProvider::checkPermission(
+ const WebURL& url) {
+ int permission;
+ Send(new ViewHostMsg_CheckNotificationPermission(
+ routing_id(),
+ url,
+ &permission));
+ return static_cast<WebNotificationPresenter::Permission>(permission);
+}
+
+void NotificationProvider::requestPermission(
+ const WebSecurityOrigin& origin,
+ WebNotificationPermissionCallback* callback) {
+ // We only request permission in response to a user gesture.
+ if (!render_view()->webview()->mainFrame()->isProcessingUserGesture())
+ return;
+
+ int id = manager_.RegisterPermissionRequest(callback);
+
+ Send(new ViewHostMsg_RequestNotificationPermission(routing_id(),
+ GURL(origin.toString()),
+ id));
+}
+
+bool NotificationProvider::OnMessageReceived(const IPC::Message& message) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(NotificationProvider, message)
+ IPC_MESSAGE_HANDLER(ViewMsg_PostDisplayToNotificationObject, OnDisplay);
+ IPC_MESSAGE_HANDLER(ViewMsg_PostErrorToNotificationObject, OnError);
+ IPC_MESSAGE_HANDLER(ViewMsg_PostCloseToNotificationObject, OnClose);
+ IPC_MESSAGE_HANDLER(ViewMsg_PostClickToNotificationObject, OnClick);
+ IPC_MESSAGE_HANDLER(ViewMsg_PermissionRequestDone,
+ OnPermissionRequestComplete);
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+
+ if (message.type() == ViewMsg_Navigate::ID)
+ OnNavigate(); // Don't want to swallow the message.
+
+ return handled;
+}
+
+bool NotificationProvider::ShowHTML(const WebNotification& notification,
+ int id) {
+ // Disallow HTML notifications from unwanted schemes. javascript:
+ // in particular allows unwanted cross-domain access.
+ GURL url = notification.url();
+ if (!url.SchemeIs(chrome::kHttpScheme) &&
+ !url.SchemeIs(chrome::kHttpsScheme) &&
+ !url.SchemeIs(chrome::kExtensionScheme) &&
+ !url.SchemeIs(chrome::kDataScheme))
+ return false;
+
+ DCHECK(notification.isHTML());
+ ViewHostMsg_ShowNotification_Params params;
+ params.origin =
+ GURL(render_view()->webview()->mainFrame()->url()).GetOrigin();
+ params.is_html = true;
+ params.contents_url = notification.url();
+ params.notification_id = id;
+ params.replace_id = notification.replaceId();
+ return Send(new ViewHostMsg_ShowDesktopNotification(routing_id(), params));
+}
+
+bool NotificationProvider::ShowText(const WebNotification& notification,
+ int id) {
+ DCHECK(!notification.isHTML());
+ ViewHostMsg_ShowNotification_Params params;
+ params.is_html = false;
+ params.origin = GURL(
+ render_view()->webview()->mainFrame()->url()).GetOrigin();
+ params.icon_url = notification.iconURL();
+ params.title = notification.title();
+ params.body = notification.body();
+ params.direction = notification.direction();
+ params.notification_id = id;
+ params.replace_id = notification.replaceId();
+ return Send(new ViewHostMsg_ShowDesktopNotification(routing_id(), params));
+}
+
+void NotificationProvider::OnDisplay(int id) {
+ WebNotification notification;
+ bool found = manager_.GetNotification(id, &notification);
+ // |found| may be false if the WebNotification went out of scope in
+ // the page before it was actually displayed to the user.
+ if (found)
+ notification.dispatchDisplayEvent();
+}
+
+void NotificationProvider::OnError(int id, const WebString& message) {
+ WebNotification notification;
+ bool found = manager_.GetNotification(id, &notification);
+ // |found| may be false if the WebNotification went out of scope in
+ // the page before the error occurred.
+ if (found)
+ notification.dispatchErrorEvent(message);
+}
+
+void NotificationProvider::OnClose(int id, bool by_user) {
+ WebNotification notification;
+ bool found = manager_.GetNotification(id, &notification);
+ // |found| may be false if the WebNotification went out of scope in
+ // the page before the associated toast was closed by the user.
+ if (found) {
+ notification.dispatchCloseEvent(by_user);
+ manager_.UnregisterNotification(id);
+ }
+}
+
+void NotificationProvider::OnClick(int id) {
+ WebNotification notification;
+ bool found = manager_.GetNotification(id, &notification);
+ // |found| may be false if the WebNotification went out of scope in
+ // the page before the associated toast was clicked on.
+ if (found)
+ notification.dispatchClickEvent();
+}
+
+void NotificationProvider::OnPermissionRequestComplete(int id) {
+ WebNotificationPermissionCallback* callback = manager_.GetCallback(id);
+ DCHECK(callback);
+ callback->permissionRequestComplete();
+ manager_.OnPermissionRequestComplete(id);
+}
+
+void NotificationProvider::OnNavigate() {
+ manager_.Clear();
+}
diff --git a/content/renderer/notification_provider.h b/content/renderer/notification_provider.h
new file mode 100644
index 0000000..32abdee
--- /dev/null
+++ b/content/renderer/notification_provider.h
@@ -0,0 +1,58 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_NOTIFICATION_PROVIDER_H_
+#define CONTENT_RENDERER_NOTIFICATION_PROVIDER_H_
+#pragma once
+
+#include "chrome/common/desktop_notifications/active_notification_tracker.h"
+#include "chrome/renderer/render_view_observer.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebNotification.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebNotificationPresenter.h"
+
+namespace WebKit {
+class WebNotificationPermissionCallback;
+}
+
+// NotificationProvider class is owned by the RenderView. Only
+// to be used on the main thread.
+class NotificationProvider : public RenderViewObserver,
+ public WebKit::WebNotificationPresenter {
+ public:
+ explicit NotificationProvider(RenderView* render_view);
+ virtual ~NotificationProvider();
+
+ private:
+ // RenderView::Observer implementation.
+ virtual bool OnMessageReceived(const IPC::Message& message);
+
+ // WebKit::WebNotificationPresenter interface.
+ virtual bool show(const WebKit::WebNotification& proxy);
+ virtual void cancel(const WebKit::WebNotification& proxy);
+ virtual void objectDestroyed(const WebKit::WebNotification& proxy);
+ virtual WebKit::WebNotificationPresenter::Permission checkPermission(
+ const WebKit::WebURL& url);
+ virtual void requestPermission(const WebKit::WebSecurityOrigin& origin,
+ WebKit::WebNotificationPermissionCallback* callback);
+
+ // Internal methods used to show notifications.
+ bool ShowHTML(const WebKit::WebNotification& notification, int id);
+ bool ShowText(const WebKit::WebNotification& notification, int id);
+
+ // IPC handlers.
+ void OnDisplay(int id);
+ void OnError(int id, const WebKit::WebString& message);
+ void OnClose(int id, bool by_user);
+ void OnClick(int id);
+ void OnPermissionRequestComplete(int id);
+ void OnNavigate();
+
+ // A tracker object which manages the active notifications and the IDs
+ // that are used to refer to them over IPC.
+ ActiveNotificationTracker manager_;
+
+ DISALLOW_COPY_AND_ASSIGN(NotificationProvider);
+};
+
+#endif // CONTENT_RENDERER_NOTIFICATION_PROVIDER_H_
diff --git a/content/renderer/speech_input_dispatcher.cc b/content/renderer/speech_input_dispatcher.cc
new file mode 100644
index 0000000..8175e40
--- /dev/null
+++ b/content/renderer/speech_input_dispatcher.cc
@@ -0,0 +1,95 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/speech_input_dispatcher.h"
+
+#include "base/utf_string_conversions.h"
+#include "chrome/renderer/render_view.h"
+#include "content/common/speech_input_messages.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebSize.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebSpeechInputListener.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
+
+using WebKit::WebFrame;
+
+SpeechInputDispatcher::SpeechInputDispatcher(
+ RenderView* render_view,
+ WebKit::WebSpeechInputListener* listener)
+ : RenderViewObserver(render_view),
+ listener_(listener) {
+}
+
+bool SpeechInputDispatcher::OnMessageReceived(const IPC::Message& message) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(SpeechInputDispatcher, message)
+ IPC_MESSAGE_HANDLER(SpeechInputMsg_SetRecognitionResult,
+ OnSpeechRecognitionResult)
+ IPC_MESSAGE_HANDLER(SpeechInputMsg_RecordingComplete,
+ OnSpeechRecordingComplete)
+ IPC_MESSAGE_HANDLER(SpeechInputMsg_RecognitionComplete,
+ OnSpeechRecognitionComplete)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+bool SpeechInputDispatcher::startRecognition(
+ int request_id,
+ const WebKit::WebRect& element_rect,
+ const WebKit::WebString& language,
+ const WebKit::WebString& grammar,
+ const WebKit::WebSecurityOrigin& origin) {
+ VLOG(1) << "SpeechInputDispatcher::startRecognition enter";
+
+ SpeechInputHostMsg_StartRecognition_Params params;
+ params.grammar = UTF16ToUTF8(grammar);
+ params.language = UTF16ToUTF8(language);
+ params.origin_url = UTF16ToUTF8(origin.toString());
+ params.render_view_id = routing_id();
+ params.request_id = request_id;
+ gfx::Size scroll = render_view()->webview()->mainFrame()->scrollOffset();
+ params.element_rect = element_rect;
+ params.element_rect.Offset(-scroll.width(), -scroll.height());
+
+ Send(new SpeechInputHostMsg_StartRecognition(params));
+ VLOG(1) << "SpeechInputDispatcher::startRecognition exit";
+ return true;
+}
+
+void SpeechInputDispatcher::cancelRecognition(int request_id) {
+ VLOG(1) << "SpeechInputDispatcher::cancelRecognition enter";
+ Send(new SpeechInputHostMsg_CancelRecognition(routing_id(), request_id));
+ VLOG(1) << "SpeechInputDispatcher::cancelRecognition exit";
+}
+
+void SpeechInputDispatcher::stopRecording(int request_id) {
+ VLOG(1) << "SpeechInputDispatcher::stopRecording enter";
+ Send(new SpeechInputHostMsg_StopRecording(routing_id(), request_id));
+ VLOG(1) << "SpeechInputDispatcher::stopRecording exit";
+}
+
+void SpeechInputDispatcher::OnSpeechRecognitionResult(
+ int request_id, const speech_input::SpeechInputResultArray& result) {
+ VLOG(1) << "SpeechInputDispatcher::OnSpeechRecognitionResult enter";
+ WebKit::WebSpeechInputResultArray webkit_result(result.size());
+ for (size_t i = 0; i < result.size(); ++i)
+ webkit_result[i].set(result[i].utterance, result[i].confidence);
+ listener_->setRecognitionResult(request_id, webkit_result);
+ VLOG(1) << "SpeechInputDispatcher::OnSpeechRecognitionResult exit";
+}
+
+void SpeechInputDispatcher::OnSpeechRecordingComplete(int request_id) {
+ VLOG(1) << "SpeechInputDispatcher::OnSpeechRecordingComplete enter";
+ listener_->didCompleteRecording(request_id);
+ VLOG(1) << "SpeechInputDispatcher::OnSpeechRecordingComplete exit";
+}
+
+void SpeechInputDispatcher::OnSpeechRecognitionComplete(int request_id) {
+ VLOG(1) << "SpeechInputDispatcher::OnSpeechRecognitionComplete enter";
+ listener_->didCompleteRecognition(request_id);
+ VLOG(1) << "SpeechInputDispatcher::OnSpeechRecognitionComplete exit";
+}
diff --git a/content/renderer/speech_input_dispatcher.h b/content/renderer/speech_input_dispatcher.h
new file mode 100644
index 0000000..44513bb
--- /dev/null
+++ b/content/renderer/speech_input_dispatcher.h
@@ -0,0 +1,51 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_SPEECH_INPUT_DISPATCHER_H_
+#define CONTENT_RENDERER_SPEECH_INPUT_DISPATCHER_H_
+
+#include "base/basictypes.h"
+#include "chrome/renderer/render_view_observer.h"
+#include "content/common/speech_input_result.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebSpeechInputController.h"
+
+class GURL;
+
+namespace WebKit {
+class WebSpeechInputListener;
+}
+
+// SpeechInputDispatcher is a delegate for speech input messages used by WebKit.
+// It's the complement of SpeechInputDispatcherHost (owned by RenderViewHost).
+class SpeechInputDispatcher : public RenderViewObserver,
+ public WebKit::WebSpeechInputController {
+ public:
+ SpeechInputDispatcher(RenderView* render_view,
+ WebKit::WebSpeechInputListener* listener);
+
+ private:
+ // RenderView::Observer implementation.
+ virtual bool OnMessageReceived(const IPC::Message& message);
+
+ // WebKit::WebSpeechInputController.
+ virtual bool startRecognition(int request_id,
+ const WebKit::WebRect& element_rect,
+ const WebKit::WebString& language,
+ const WebKit::WebString& grammar,
+ const WebKit::WebSecurityOrigin& origin);
+
+ virtual void cancelRecognition(int request_id);
+ virtual void stopRecording(int request_id);
+
+ void OnSpeechRecognitionResult(
+ int request_id, const speech_input::SpeechInputResultArray& result);
+ void OnSpeechRecordingComplete(int request_id);
+ void OnSpeechRecognitionComplete(int request_id);
+
+ WebKit::WebSpeechInputListener* listener_;
+
+ DISALLOW_COPY_AND_ASSIGN(SpeechInputDispatcher);
+};
+
+#endif // CHROME_RENDERER_SPEECH_INPUT_DISPATCHER_H_